8

在我的应用程序中,我能够从数据库中清除所有数据。此操作完成后,将解析捆绑的 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];

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

4

1 回答 1

13

无法从此 NSManagedObjectContext 的协调器访问对象的持久存储

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

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

于 2013-07-12T20:16:06.640 回答