合并NSManagedObjectContexts(多线程)之间的更改

时间:2013-06-19 12:47:32

标签: ios core-data concurrency nsmanagedobjectcontext

我遇到问题/崩溃合并不同NSManagedObjectContexts(iOS 6.1,Xcode 4.6)的数据。

大多数情况下,上升的错误如下:

CoreData:错误:严重的应用程序错误。在Core Data更改处理期间捕获到异常。这通常是NSManagedObjectContextObjectsDidChangeNotification的观察者中的错误。 userInfo(null)

仍然有效

有一次我收到了这个错误: NSManagedObjectContextDidSaveNotification的观察者非法抛出异常。保存的对象= {$ OBJLIST}且exception = statement仍然有效,userInfo =(null)

可悲的是,我得到的stacktraces没有任何价值。它们只显示CoreData内部符号(如果有的话)。

我们的CoreData堆栈:

  • 所有线程共享的1个NSPersistentStoreLocator
  • 每个线程1个唯一的MOC(首次创建时创建)
    • 所有MOC都保存在词典中

为通知NSManagedObjectContextDidSaveNotification添加一个观察者,以便在保存到商店时更新MOC。定义的选择器在除了执行保存操作的线程/上下文之外的每个其他线程/上下文上调用mergeChangesFromContextDidSaveNotification。

+ (void)mergeChanges:(NSNotification *)notification {
    NSManagedObjectContext *ctx;
    for ( NSNumber *threadId in [__managedObjectContexts keyEnumerator] ) {
        ctx = [__managedObjectContexts objectForKey:threadId];
        if ( notification.object != ctx ) {
            [ctx mergeChangesFromContextDidSaveNotification:notification];
        }
    }
}

产生错误的步骤:

在后台线程中,正在删除不再需要的CoreData数据对象(未被其他对象引用)。​​

[[CDUtils managedObjectContext] deleteObject:obj];
[[CDUtils managedObjectContext] save:&error];

发生这种情况时,用户可以在整个应用程序中导航。用户交互(即打开一个tableview)可以触发主线程的moc上的executeFetch调用。 每个线程使用相同的NSPersistentStoreLocator,但使用不同的/唯一的MOC。

我们尝试了使用NSLocks锁定的不同方法以及NSPersistentStoreLocator上用于线程安全的锁定。即通过锁定/解锁或将两种方法封装在同一个锁定/解锁中来封闭mergeChanges方法和保存操作。可悲的是,到目前为止我们没有成功。

[__storeCoordinator lock];
[__storeCoordinator unlock];

我会感谢您提供给我解决方案的每一条建议。谢谢你的时间!

1 个答案:

答案 0 :(得分:0)

对于有兴趣的人。我设法使多个线程/ MOC的工作。通过正确锁定PSC和MOC,我基本上解决了原来的问题/我遇到的错误。出现的下一个问题是如何知道它是否在上下文中保存mergeChanges。我不能锁定也不应该在没有正在运行的线程的MOC上mergeChanges。但我怎么知道线程是否正在运行?如果我只是检查NSThreads“isExecuting” - 方法可能会发生线程在我检查BOOL之后退出。我正在尝试一种更简单的方法,现在我只是合并到主线程中。