您的位置:首页 > 运维架构

使用 FMDB 框架时候,error opening!: 14错误的修改问题

2015-05-01 15:14 363 查看
测试环境: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 文件夹都已经删除了。这个时候如果再去读取数据库数据的时候会发现直接报错,无法创建数据库。原因就是cache 这个文件夹其实已经不存在了(被删除了),FMDB 创建SQLite数据库文件的时候,不能够递归创建不存在的文件夹,因此这个时候出现了错误。

解决方案:

1、清理缓存的时候,再自己建一次 cache 文件夹。

2、自己在创建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在做缓存的时候,如果文件夹不存在就会立即创建一个。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐