NSPersistentStoreCoordinator 在尝试访问 sqlite 文件时引发错误 NSSQLiteErrorDomain=26

Posted

技术标签:

【中文标题】NSPersistentStoreCoordinator 在尝试访问 sqlite 文件时引发错误 NSSQLiteErrorDomain=26【英文标题】:NSPersistentStoreCoordinator raises error NSSQLiteErrorDomain=26 when trying to access sqlite file 【发布时间】:2015-11-03 10:27:00 【问题描述】:

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

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

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

    我的代码中是否存在阻止我访问 sqlite 文件的缺陷? 除了缺少文件之外,是否还有其他可能发生此错误?

这是我的模型单例初始化源代码和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】:

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) 下生成它。

【讨论】:

以上是关于NSPersistentStoreCoordinator 在尝试访问 sqlite 文件时引发错误 NSSQLiteErrorDomain=26的主要内容,如果未能解决你的问题,请参考以下文章