我已经阅读了Marcus Zarra在他的Core Data书中关于多线程的章节,并且仔细研究了他的示例代码。但是他的代码和其他我在其他地方找到的代码似乎都专注于不需要相互了解的后台进程。这些示例适用于导入树形结构,但它们并没有涉及导入更一般(复杂)的结构,例如有向无环图。
在我的情况下,我正在尝试解析C++类层次结构,并希望尽可能使用NSOperations。我想为每个遇到的类创建一个NSManagedObject实例,并且我想在保存一个实例时合并不同的NSManagedObjectContexts。
顺便说一句:我能够使用单个NSOperation使所有文件迭代并逐个解析。在此实现中,-mergeChanges:方法调用主线程MOC上的-mergeChangesFromContextDidSaveNotification:效果很好。
但理想情况下,我希望有一个NSOperation遍历源文件并生成解析每个文件的NSOperations。我尝试了几种方法,但似乎做不对。最有前途的方法是让每个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”。如果为真,则使用缓存的NSNotification在本地MOC上调用-mergeChangesFromContextDidSaveNotification。然后重置needsToMerge。如果通知是在本地发起的,则告诉主线程在其MOC上执行-mergeChangesFromContextDidSaveNotification。
我确信这不能正常工作,并且我会收到以下警告:
取消对当前线程堆栈上的objc代码调用会使其不安全。
我还尝试使用NSPeristentStoreCoordinator的锁来控制访问 - 但如果在调用NSManagedObjectContext的-save:方法时持有它,这可能会引起问题,因为-save:会通知感兴趣的观察者保存事件,并且-mergeChangesFromContextDidSaveNotification似乎会阻塞尝试获取PSC的锁。
看起来这应该更容易些。