首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与-[ _coordinator_you_never_successfully_opened_the_database_device_locked:] iOS9 ]崩溃

与-[ _coordinator_you_never_successfully_opened_the_database_device_locked:] iOS9 ]崩溃
EN

Stack Overflow用户
提问于 2015-10-21 05:23:08
回答 2查看 3.7K关注 0票数 5

我的应用程序最近从只发生在iOS9上的crashlytics中获得了这些崩溃。

致命例外: NSInternalInconsistencyException 此NSPersistentStoreCoordinator没有持久存储(损坏的文件)。它不能执行保存操作。

报告中的最后一个呼吁是

代码语言:javascript
复制
-[NSPersistentStoreCoordinator _coordinator_you_never_successfully_opened_the_database_device_locked:]

NSPersistentStoreCoordinator就是这样创建的

代码语言:javascript
复制
 - (NSPersistentStoreCoordinator *)persistentStoreCoordinator{
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }

    AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

    NSURL *storeURL = [[delegate applicationDocumentsDirectory] URLByAppendingPathComponent:@"database.sqlite"];

    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];

    NSError* error = nil;

    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                   configuration:nil
                                                             URL:storeURL
                                                         options:@{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES} error:&error])
    {
        NSLog(@"Error adding persistent store. %@, %@", error, error.userInfo);
        return nil;
    }

    return _persistentStoreCoordinator;
}

有人知道是什么导致了这些车祸吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-10-21 14:28:53

我在iOS9上没有经历过这样的错误。然而,您应该查看您的日志,看看您有哪些错误。您是否可能在PSC创建时遇到“添加持久存储的错误”?

您的方法有一个问题,如果您遇到该错误,随后的调用将返回一个PSC,这个PSC既不是零,也不是正确的设置。

原因是在成功安装_persistentStoreCoordinator之前分配它。因此,如果有任何错误,则返回零,但下次调用该方法时,将返回没有存储的PSC。

无论如何,您应该更改该方法,以便只返回零或完全操作的PSC。

我会把这个方法变成这样的。然而,Note表示,我永远不会构建这样的核心数据堆栈。但是,至少下面的代码将修复您的错误,您可以返回部分组成的PSC。

代码语言:javascript
复制
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator{
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }

    AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
    NSURL *storeURL = [[delegate applicationDocumentsDirectory]
        URLByAppendingPathComponent:@"database.sqlite"];

    NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc]
        initWithManagedObjectModel:self.managedObjectModel];
    NSError *error = nil;
    if (![psc addPersistentStoreWithType:NSSQLiteStoreType
                           configuration:nil
                                     URL:storeURL
                                 options:@{NSMigratePersistentStoresAutomaticallyOption:@YES,
                                           NSInferMappingModelAutomaticallyOption:@YES}
                                   error:&error]) {
        NSLog(@"Error adding persistent store. %@, %@", error, error.userInfo);
    } else {
        _persistentStoreCoordinator = psc;
    }

    return _persistentStoreCoordinator;
}

编辑

在评论中没有足够的空间回答你的问题,所以我把它放在这里。

@JodyHagins -而且,您提到不会像这样构造堆栈,您能让我知道我的堆栈有什么问题吗?- AWillian

我这么说是因为您发布的代码与默认的Xcode核心数据模板非常相似。您可以调用app委托来获取目录,这表明它不在app委托中,这是很好的。

但是,该方法表明您从"anywhere“访问它,这表明您的堆栈不是以我构建堆栈的方式构建的(特别是因为您还包括迁移选项)。

我不是故意说你做的是错的,只是这不是我会怎么做的。

现在,我会第一个说我所做的就是我所做的.我不认为这是正确的方法..。就按我的方式。事实上,我没有见过其他人真正做我所做的事情(我实际上是子类NSManagedObjectContext,尽管我不介意警告,并且远离那些挑剔的部分)。这本身可能表明,我所做的可能不适合你或其他任何人。但是,我发现它适合我自己,以及我必须实现的非常复杂的应用程序。

那么,我将如何构建一个堆栈呢?

嗯,这比回答要深入得多,所以我会说得很简短。这也取决于哪种类型的堆栈父/子,兄弟姐妹有相同的PSC,表兄弟姐妹有不同的PSC,但相同的商店。

首先,我不提供对模型和协调器的单独访问。您可以轻松地从上下文中访问这些内容,结果通常会导致比其价值更多的问题。

除了测试和简单的例子,我总是异步地创建我的MOC,如下所示.

代码语言:javascript
复制
+ (void)createWithConcurrencyType:(NSManagedObjectContextConcurrencyType)concurrencyType
                       completion:(void(^)(NSManagedObjectContext *moc, NSError *error))completion;

MOM被创建并分配给PSC,PSC被创建并分配给MOC。这种情况是异步发生的,因此打开和初始化的潜在长进程可以在后台线程中完成。完成处理程序是在performBlock中调用的,因此可以干净地使用MOC。这也防止在MOC完全安装和读取之前使用。

即使使用主队列并发类型调用,所有工作都是在后台线程中完成的,因此只在主线程上调用完成。

在创建用于导入和临时目的的相关MOC时,我也使用相同的模式。

票数 4
EN

Stack Overflow用户

发布于 2016-02-16 02:42:44

来自Apple论坛这里的答案也解释了一个可能的原因和解决方案。

原因在于描述符:当设备被锁定时,应用程序试图打开持久存储,代码被数据保护API绊倒。 这就是你在新设备和新iOS版本上遇到的问题,因为新设备足够快地让应用程序在数据保护代码完成转换之前运行。

这类问题的解决办法如下所示

您几乎必须进入启动代码,并重写它,以便检查是否有受保护的数据,然后将核心数据的启动推迟到applicationProtectedDataDidBecomeAvailable。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33251528

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档