环境
测试环境:Xcode6.2 (6C131e) iPhone 4S模拟器
系统版本:IOS 7.1
框架:FMDB、SDWebImage。
问题
今天测试代码的时候,发现程序在运行的时候,只要清空缓存,立即去数据库查找数据的时候,FMDB 就会报出错误:
error opening!: 14
Could not create database queue for path XXX
下面是出现错误的代码:
数据库访问的代码
(void)setup
{
// 1、获取沙盒中数据库的路径
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"test.sqlite"];
// 2、创建队列
_queue = [FMDatabaseQueue databaseQueueWithPath:fullPath];
// 3、创建表
[_queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"create table if not exists ...);"];
}];
}
// ...
+ (NSArray *)statusWithParam:(MLHomeStatusesParam *)param
{
[self setup]; // 这里出错
NSLog(@"statusWithParam----%@",_queue);
__block NSMutableArray *statusArray = nil;
// _queue使用的时dispatch_sync方法。因此就是在主线程中查询数据库的
[_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];
};
这里可以看到,在清理缓存,其实是整个 cache 文件夹都已经删除了。而FMDB 创建SQLite数据库文件的时候,不能够递归创建不存在的文件夹,因此这个时候出现了错误。
解决方案:
- 清理缓存的时候,再自己建一次 cache 文件夹。
- 自己在创建SQLite 数据库文件的时候判断一下目标文件夹是否存在,不存在就创建一个。
针对以上的代码做出的修改:
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、获取沙盒中数据库的路径
NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *fullPath = [path stringByAppendingPathComponent:@"test.sqlite"];
// 2、判断 caches 文件夹是否存在.不存在则创建
NSFileManager *manager = [NSFileManager defaultManager];
BOOL tag = [manager fileExistsAtPath:path isDirectory:NULL];
if (!tag) {
[manager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:NULL];
}
// 2、创建队列
_queue = [FMDatabaseQueue databaseQueueWithPath:fullPath];
// 3、创建表
[_queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"create table if not exists ....);"];
}];
}
// ....
+ (NSArray *)statusWithParam:(MLHomeStatusesParam *)param
{
[self setup]; // 这里已经不再报错了
__block NSMutableArray *statusArray = nil;
// _queue使用的时dispatch_sync方法。因此就是在主线程中查询数据库的
[_queue inDatabase:^(FMDatabase *db) {
// ...
}];
[_queue close];
return statusArray;
}
在测试过程中,发现 SDWebImage 不会出现这个问题。SDWebImage在做缓存的时候,如果文件夹不存在就会立即创建一个。
网友评论