这更像是为什么这项工作并没有什么问题......
我在多个线程上使用CoreData。我有两个主线程产生的线程,它们都执行类似的调用:
id observerObject = [notificationCenter addObserverForName:NSManagedObjectContextDidSaveNotification
object:secondManagedObjectContext
queue:nil
usingBlock:^(NSNotification *saveNotification) {
dispatch_async(dispatch_get_main_queue(), ^{
[mainThreadManagedObjectContext mergeChangesFromContextDidSaveNotification:saveNotification];
});
}];
[secondManagedObjectContext save:nil];
[notificationCenter removeObserver:observerObject
name:NSManagedObjectContextDidSaveNotification
object:syncManagedObjectContext];
这似乎工作正常,但之前我在通知中心这样做并遇到了一些问题:
id observerObject = [notificationCenter addObserverForName:NSManagedObjectContextDidSaveNotification
object:secondManagedObjectContext
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *saveNotification) {
[mainThreadManagedObjectContext mergeChangesFromContextDidSaveNotification:saveNotification];
}];
这有时会起作用,但有时候XCode会在启动时暂停并在调用时放下一个绿色断点,只列出线程及其编号,但没有错误。 (注意:只有在我生成两个或多个线程时才会出现此问题。)
罪魁祸首似乎是:[NSOperationQueue mainQueue],但我似乎无法弄清楚为什么它会使线程暂停。我能够在调试器中继续按下并继续...但我不明白为什么它以这种方式运行。
我认为我做错了什么,我担心我的新方式可能只是一个黑客。
感谢您的帮助!
答案 0 :(得分:1)
我认为第一个因为异步调度而起作用。如果没有这个,通知中心将暂停,直到任何特定通知完成。你得到的问题听起来像一个典型的停顿,代码只是暂停而没有错误,直到调试器最终超时。
答案 1 :(得分:0)
不确定这是否有帮助,但在队列中没有nil的情况下尝试使用通用队列。看一下apple docs中的接待员设计模式。
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
答案 2 :(得分:0)
第一个代码示例中的合并在主线程上正确分派,主线程很可能也是创建moc的线程。
在第二个示例中,如果通知是在bg线程上发出的,则合并将在后台线程上执行(通知回调总是在发布通知的同一线程上调用)。
BTW,我现在宁愿使用NSManagedObjectContext自己的performBlock:
方法(> = iOS 5),而不是使用主队列。在带有ARC的iOS5上,此代码归结为:
__weak typeof(self) weakSelf = self;
[[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
[weakSelf.moc performBlock:^{
[weakSelf.moc mergeChangesFromContextDidSaveNotification:note];
}];
}];