“'NSInternalInconsistencyException'的替代原因,原因:'此NSPersistentStoreCoordinator没有持久存储。'”

时间:2014-01-21 17:29:23

标签: core-data

感谢阅读。我们在iOS应用程序上收到了崩溃报告,但出现以下错误:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This NSPersistentStoreCoordinator has no persistent stores.  It cannot perform a save operation.'

当我们的主队列NSManagedObjectContext尝试保存时会发生这种情况:

BOOL saved = [managedObjectContext save:&error];

在通过以下方式提交的块中发生:

[managedObjectContext performBlockAndWait:saveBlock];

互联网(尤其是SO)充满了对此错误的解释,这表明我们从未有过持久存储cooridinater(我们在构建核心数据堆时未能正确创建它)。但是,如果没有持久存储协调器,我们很难看到如何在程序执行中达到这一点。对于踢,我注释掉我们设置持久存储的行,应用程序几乎立即崩溃(没有达到我们的保存方法)。

有没有人知道这个例外是否有其他原因,或者它是否总是因为没有持久存储?有没有办法失去持久存储?

多一点颜色:我们使用父/子NSManagedObjectContexts来加载后台线程中的数据。完整的保存方法如下所示:

-(void)saveWithManagedObjectContext:(NSManagedObjectContext*)managedObjectContext successHandler:(void (^)())successHandler failureHandler:(void (^)(NSManagedObjectContext* managedObjectContext, NSError*))failureHandler
{
    void(^saveBlock)() = ^() {
        NSError *error = nil;
        BOOL saved = [managedObjectContext save:&error];
        if (!saved) {
            if (error != nil) {
                NSLog(@"Unresolved error saving %@, %@", error, [error userInfo]);
            }
            failureHandler(managedObjectContext, error);
        } else {
            if (managedObjectContext.parentContext != nil) {
                [self saveWithManagedObjectContext: managedObjectContext.parentContext successHandler:successHandler failureHandler:failureHandler];
            } else {
                successHandler();
            }
        }
    };

    BOOL isMainContext = managedObjectContext.parentContext == nil;

    if (isMainContext) {
        [managedObjectContext performBlockAndWait:saveBlock];
    } else {
        [managedObjectContext performBlock:saveBlock];
    }
}

可以从后台线程调用它,它将通过performBlock在NSManagedObjectContext上调用save:然后在父NSManagedObjectContext上以递归方式调用此方法以保存它。当应用程序崩溃时,它总是在主线程上有意义,因为主队列上下文是唯一需要持久存储的上下文。

非常感谢您的帮助。我曾经发帖到devforums.apple.com,所以如果你已经两次见过这件事,我很抱歉。

3 个答案:

答案 0 :(得分:1)

基本上有两个地方可以看。

首先,检查首次将持久性存储添加到Core Data堆栈时会发生什么。如果您使用Apple模板,那将在应用程序委托中,但是当应用程序初始化时,通常会在代码中的某个位置调用

addPersistentStoreWithType:configuration:URL:options:error:

其次,当您提到后台线程并且因为您将托管对象上下文传递给您的方法时,您可能有子上下文。在创建子上下文时,请检查是否已为子上下文正确分配了有效的父上下文或存储协调器。

答案 1 :(得分:0)

遗憾的是,此错误含糊不清。我在使用配置时已经看到它,并且配置名称中存在拼写错误,或者在模型中没有配置时传入配置名称的情况下。

所以我的第一线测试是查看你的核心数据堆栈创建代码。你能将它添加到你的问题中,以便我们看一下吗?

答案 2 :(得分:0)

我与Tom Harrington做了离线通话,他们发表了无害的评论:“除非你删除它们,否则持续存储不应该消失(我假设你不这样做)。” “当我拆除核心数据堆栈时(当用户注销时)我会这样做。当我拆除堆栈时,我在我的根管理对象上下文中调用reset(我唯一参考的那个)然后删除持久性存储。但是,如果子上下文中存在挂起的更改,它们将传播到我现在的persistentstoreless root上下文,从而导致保存时崩溃。由于父母背景不能跟踪他们的孩子有充分的理由,我也不想跟踪他们。相反,我只是在调用save之前确认存在父上下文或持久存储协调器(至少有一个存储)。