【发布时间】:2011-01-15 20:44:38
【问题描述】:
我已经阅读了 Marcus Zarra 在他的 Core Data 书中关于多线程的一章,并且相当仔细地查看了他的示例代码。但是他的代码和我在其他地方找到的其他代码似乎都集中在后台进程中,而 不需要 需要相互了解。这些示例适用于导入树形结构 - 但它们不能解决更一般(复杂)结构的导入问题,例如有向无环图。
就我而言,我正在尝试解析 C++ 类层次结构,并希望使用尽可能多的 NSOperations。我想为每个遇到的类创建一个 NSManagedObject 实例,并且我想在保存时合并不同的 NSManagedObjectContexts。
顺便说一句:我能够使用一个迭代文件并一次解析一个的 NSOperation 来处理事情。在这个实现中,在主线程的 MOC 上调用 -mergeChangesFromContextDidSaveNotification: 的 -mergeChanges: 方法效果很好。
但理想情况下,我会让一个 NSOperation 迭代源文件并生成 NSOperation 来解析每个文件。我尝试了几种方法 - 但似乎无法做到正确。最有希望的是让每个 NSOperation 观察 NSManagedObjectContextDidSaveNotification。使用 -mergeChanges: 看起来像这样:
- (void) mergeChanges:(NSNotification *)notification
{
// If locally originated, then trigger main thread to merge.
if ([notification object] == [self managedObjectContext])
{
AppDelegate *appDelegate = (AppDelegate*)[[NSApplication sharedApplication] delegate];
NSManagedObjectContext *mainContext = [appDelegate managedObjectContext];
// Merge changes into the main context on the main thread
[mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
withObject:notification
waitUntilDone:YES];
return;
}
// If not locally originated, then flag need to merge with in this NSOperation's thread.
[self setNeedsToMerge:YES];
[self setMergeNotification:notification];
}
本质上,解析 NSOperation 的 main() 会定期检查 ivar 'needsToMerge'。如果是真的,那么 -mergeChangesFromContextDidSaveNotification: 在本地 MOC 上被调用并缓存了 NSNotification。然后 needsToMerge 被重置。如果通知来自本地,则通知主线程在其 MOC 上执行 -mergeChangesFromContextDidSaveNotification:。
我确信这有一个很好的理由为什么这不起作用以及为什么我得到这个:
警告:取消调用 - objc 代码 在当前线程的堆栈上 这不安全。
我也尝试使用 NSPeristentStoreCoordinator 的锁来控制访问 - 但如果它在调用 NSManagedObjectContext 的 -save: 方法期间被持有,这是有问题的,因为 -save: 将通知感兴趣的观察者保存事件和 -mergeChangesFromContextDidSaveNotification: 似乎阻塞试图获取 PSC 的锁。
似乎这应该容易得多。
【问题讨论】:
标签: multithreading core-data nsmanagedobjectcontext