環(huán)境
測(cè)試環(huán)境:Xcode6.2 (6C131e) iPhone 4S模擬器
系統(tǒng)版本:IOS 7.1
框架:FMDB蚯窥、SDWebImage。
問(wèn)題
今天測(cè)試代碼的時(shí)候,發(fā)現(xiàn)程序在運(yùn)行的時(shí)候拦赠,只要清空緩存巍沙,立即去數(shù)據(jù)庫(kù)查找數(shù)據(jù)的時(shí)候,F(xiàn)MDB 就會(huì)報(bào)出錯(cuò)誤:
error opening!: 14
Could not create database queue for path XXX
下面是出現(xiàn)錯(cuò)誤的代碼:
數(shù)據(jù)庫(kù)訪問(wèn)的代碼
(void)setup
{
// 1荷鼠、獲取沙盒中數(shù)據(jù)庫(kù)的路徑
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"test.sqlite"];
// 2句携、創(chuàng)建隊(duì)列
_queue = [FMDatabaseQueue databaseQueueWithPath:fullPath];
// 3、創(chuàng)建表
[_queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"create table if not exists ...);"];
}];
}
// ...
+ (NSArray *)statusWithParam:(MLHomeStatusesParam *)param
{
[self setup]; // 這里出錯(cuò)
NSLog(@"statusWithParam----%@",_queue);
__block NSMutableArray *statusArray = nil;
// _queue使用的時(shí)dispatch_sync方法允乐。因此就是在主線程中查詢數(shù)據(jù)庫(kù)的
[_queue inDatabase:^(FMDatabase *db) {
//....
}];
[_queue close];
return statusArray;
}
清空緩存的代碼:
clearCache.operation =^{
NSFileManager *manager = [NSFileManager defaultManager];
NSString *catchPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
[MBProgressHUD showMessage:@"正在幫您拼命情理中...."];
// 清除緩存
NSError *error;
[manager removeItemAtPath:catchPath error:&error];
[MBProgressHUD hideHUD];
};
這里可以看到矮嫉,在清理緩存,其實(shí)是整個(gè) cache 文件夾都已經(jīng)刪除了喳篇。而FMDB 創(chuàng)建SQLite數(shù)據(jù)庫(kù)文件的時(shí)候敞临,不能夠遞歸創(chuàng)建不存在的文件夾,因此這個(gè)時(shí)候出現(xiàn)了錯(cuò)誤麸澜。
解決方案:
- 清理緩存的時(shí)候挺尿,再自己建一次 cache 文件夾。
- 自己在創(chuàng)建SQLite 數(shù)據(jù)庫(kù)文件的時(shí)候判斷一下目標(biāo)文件夾是否存在炊邦,不存在就創(chuàng)建一個(gè)编矾。
針對(duì)以上的代碼做出的修改:
clearCache.operation =^{
NSFileManager *manager = [NSFileManager defaultManager];
NSString *catchPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
[MBProgressHUD showMessage:@"正在幫您拼命情理中...."];
// 清除緩存
NSError *error;
[manager removeItemAtPath:catchPath error:&error];
[manager createDirectoryAtPath:catchPath withIntermediateDirectories:YES attributes:nil error:NULL];
[MBProgressHUD hideHUD];
};
+(void)setup
{
// 1、獲取沙盒中數(shù)據(jù)庫(kù)的路徑
NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *fullPath = [path stringByAppendingPathComponent:@"test.sqlite"];
// 2馁害、判斷 caches 文件夾是否存在.不存在則創(chuàng)建
NSFileManager *manager = [NSFileManager defaultManager];
BOOL tag = [manager fileExistsAtPath:path isDirectory:NULL];
if (!tag) {
[manager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:NULL];
}
// 2窄俏、創(chuàng)建隊(duì)列
_queue = [FMDatabaseQueue databaseQueueWithPath:fullPath];
// 3、創(chuàng)建表
[_queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"create table if not exists ....);"];
}];
}
// ....
+ (NSArray *)statusWithParam:(MLHomeStatusesParam *)param
{
[self setup]; // 這里已經(jīng)不再報(bào)錯(cuò)了
__block NSMutableArray *statusArray = nil;
// _queue使用的時(shí)dispatch_sync方法碘菜。因此就是在主線程中查詢數(shù)據(jù)庫(kù)的
[_queue inDatabase:^(FMDatabase *db) {
// ...
}];
[_queue close];
return statusArray;
}
在測(cè)試過(guò)程中凹蜈,發(fā)現(xiàn) SDWebImage 不會(huì)出現(xiàn)這個(gè)問(wèn)題。SDWebImage在做緩存的時(shí)候忍啸,如果文件夾不存在就會(huì)立即創(chuàng)建一個(gè)仰坦。