我在合并不同 NSManagedObjectContexts(iOS 6.1、Xcode 4.6)的数据时遇到问题/崩溃。
大多数情况下,上升的错误如下:
CoreData:错误:严重的应用程序错误。在核心数据更改处理期间捕获到异常。这通常是 NSManagedObjectContextObjectsDidChangeNotification 观察者中的一个错误。使用 userInfo (null) 的语句仍处于活动状态
有一次我得到这个错误: NSManagedObjectContextDidSaveNotification 的观察者非法抛出异常。已保存的对象 = { $OBJLIST } 和异常 = 语句仍处于活动状态,且 userInfo = (null)
可悲的是,我得到的堆栈跟踪没有任何价值。它们只显示 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];
我会很感激你给我的每一条建议来解决问题。感谢您的时间!