【问题标题】:Core Data Error After Recreating Persistant Store创建持久存储后的核心数据错误
【发布时间】:2013-07-11 09:58:55
【问题描述】:

在我的应用程序中,我可以从数据库中清除所有数据。此操作完成后,将解析捆绑的 JSON,然后将其保存到数据库中(以便将数据库返回到默认状态)。解析和保存此 JSON 的操作在任何情况下都可以正常工作,除非在清除和重新创建持久存储之后,在这种情况下我得到“NSInvalidArgumentException”,原因是:“无法从此 NSManagedObjectContext 的协调器访问对象的持久存储”。在后台上下文中保存后尝试在我的主线程上下文上调用 mergeChangesFromContextDidSaveNotification 时会引发此异常。

重新创建存储在主线程上执行,而解析和保存总是在后台线程上进行。这是我的托管对象上下文的 getter,以确保线程安全:

- (NSManagedObjectContext *)managedObjectContext {

    NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary];
    NSManagedObjectContext *threadContext = threadDictionary[ckCoreDataThreadKey];

    if (!threadContext) {
        threadContext = [self newManagedObjectContext];
        threadDictionary[ckCoreDataThreadKey] = threadContext;
    }

    return threadContext;
}

newManagedObjectContext 方法为所有新实例提供相同的 NSPersistentStoreCoordinator 对象。

这是用于清除存储的代码(始终在主线程上执行):

[self.managedObjectContext lock];
[self.managedObjectContext reset]; //to drop pending changes
                                       //delete the store from the current managedObjectContext
if ([[self.managedObjectContext persistentStoreCoordinator] removePersistentStore:[[[self.managedObjectContext persistentStoreCoordinator] persistentStores] lastObject] error:error]) {
    [[NSFileManager defaultManager] removeItemAtURL:storeURL error:error];

    [[self.managedObjectContext persistentStoreCoordinator] addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:error]; //recreates the persistent store

    [self addSkipBackupAttributeToItemAtURL:storeURL];
}

[self.managedObjectContext unlock];

奇怪的是,同样的代码在其他项目中运行良好,除了数据的内容之外没有任何区别。非常感谢任何帮助!

【问题讨论】:

    标签: ios core-data nsmanagedobjectcontext nspersistentstore


    【解决方案1】:

    “无法从这个 NSManagedObjectContext 的协调器访问对象的持久存储”

    此消息表示您尝试使用从刚刚删除的数据存储中加载的托管对象。您从协调器中删除了持久存储并删除了存储文件,但您仍然至少有一个从该存储加载的NSManagedObject。你不能再使用这些对象,因为如果你这样做了,你会得到这个特定的异常。 在在第二个 sn-p 中对核心数据堆栈进行核处理之前,请确保删除任何现有的托管对象。

    至于为什么这适用于不同的应用程序,很可能该应用程序没有保留过时的托管对象。

    【讨论】:

    • 确实,你是对的。这个项目和我的其他项目的不同之处在于,在这个应用程序中,根视图控制器管理一个获取的结果控制器,当商店被移除时,该控制器仍然持有对象。清除存储后删除并重新加载该控制器,现在效果很好。谢谢一百万!
    • 如果临时上下文(其父级是崩溃上下文)正在进行获取请求、设置值等,并且最后临时上下文希望将更改保存回父母。
    猜你喜欢
    • 2012-12-20
    • 1970-01-01
    • 2012-06-13
    • 2011-08-11
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多