尝试访问sqlite文件

时间:2015-11-03 10:27:01

标签: ios objective-c sqlite core-data nspersistentstore

最近我添加了一些对我的不同域模型的并发访问(它们代表了持久数据的子集)。我的崩溃报告显示我现在偶然发现了iOS7,iOS8和iOS上的一些错误。 iOS9,似乎都基于

  

NSSQLiteErrorDomain = 26,NSUnderlyingException =路径中的文件没有   似乎是一个SQLite数据库   在我在源代码中标记的位置

不幸的是我无法重现它,我无法想象某些设备上不存在sqlite文件,因为我将它与我的应用程序包一起发送。

  1. 我的代码中是否存在阻止我访问sqlite文件的缺陷?
  2. 除了丢失文件外,还有其他可能发生此错误吗?
  3. 这是我的模型单例和NSManagedObjectContext

    初始化的源代码
    + (id) sharedModel {
        static id sharedModel = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^ {
            sharedModel = [[self alloc] initWithStoreURL: kDefaultStoreURL];
        });
        return sharedModel;
    }
    
    - (id) initWithStoreURL:(NSURL *)storeURL {
        self = [super init];
        if (self) {
            // create managed object model
            NSURL * modelURL = [[NSBundle mainBundle] URLForResource: @"MyApp" withExtension: @"momd"];
            NSManagedObjectModel *objectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL: modelURL];
            // create persistent store coordinator
            NSError * error = nil;
            NSPersistentStoreCoordinator * storeCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:objectModel];
            if (![storeCoordinator addPersistentStoreWithType: NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
                CLS_LOG(@"Unresolved error %@, %@", error, [error userInfo]); 
                // this is where the error occurs
                abort();
            }
            // init managedObjectContext
            context = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSMainQueueConcurrencyType];
            [context setPersistentStoreCoordinator:storeCoordinator];
            _mainContext = context;
    
            _someDomainModel1 = [[SomeDomainModel1 alloc] initWithContext:_mainContext];
            _someDomainModel2 = [[SomeDomainModel2 alloc] initWithContext:_mainContext];
        }
        return self;
    }
    

1 个答案:

答案 0 :(得分:1)

initWithStoreURL可能存在问题,但如果您一直使用相同的代码,那么我可能会做出错误的假设。

你说你的SQLite商店文件是随捆绑提供的,如果是这样的话,你需要以只读方式和回滚模式打开它。

NSDictionary *storeOptions = @{
    NSReadOnlyPersistentStoreOption:@YES,
    NSSQLitePragmasOption:@{@"journal_mode":@"DELETE"}};

然后,在添加商店时使用选项。

if (![storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                    configuration:nil
                                              URL:storeURL
                                          options:storeOptions
                                            error:&error]) {
}

此外,由于您看到了这一点,因此您应该记录更多信息(例如URL和错误对象的详细信息)。

但是,您正在调用abort(),因此您应该能够从崩溃报告中获取堆栈跟踪和状态信息。

另一件事......看看你是如何生成数据库的。您应该确保以回滚模式(journal_mode = DELETE)生成它。