Multithreading 确保在收到NSManagedObjectContextObjectsIDChangeNotification之后而不是之前接收到从另一个线程发送到对象的消息
我的应用程序有一个典型的核心数据后端,包含父对象和子对象 父级Multithreading 确保在收到NSManagedObjectContextObjectsIDChangeNotification之后而不是之前接收到从另一个线程发送到对象的消息,multithreading,grand-central-dispatch,nsmanagedobjectcontext,nsnotificationcenter,Multithreading,Grand Central Dispatch,Nsmanagedobjectcontext,Nsnotificationcenter,我的应用程序有一个典型的核心数据后端,包含父对象和子对象 父级NSManagedObjectContext,moc1,具有NSMainQueueConcurrencyType 子NSManagedObjectContext,moc2,具有NSPrivateQueueConcurrencyType 我还有一个对象X,它观察moc1的nsmanagedObjectContextObjectsIDChangeNotification。此通知必须到达主线程 问题:假设对后台队列上的moc2进行了更改,然
NSManagedObjectContext
,moc1,具有NSMainQueueConcurrencyType
子NSManagedObjectContext
,moc2,具有NSPrivateQueueConcurrencyType
我还有一个对象X,它观察moc1的nsmanagedObjectContextObjectsIDChangeNotification
。此通知必须到达主线程
问题:假设对后台队列上的moc2进行了更改,然后调用[moc2 save:://code>。然后,如何在主线程上向对象X发送消息,并确保在收到NSManagedObjectContextObjectsDidChangeNotification
之后而不是之前收到该消息?致电:
[moc2 save:NULL]; // causes X to get NSManagedObjectContextObjectsDidChangeNotification for moc1...eventually
dispatch_async(dispatch_get_main_queue(), ^{
[X iHopeYouGetThisAfterYouGotTheNotification];
};
即使您根据经验观察到这样一个块是在通知之后执行的,依赖它也将假定未记录的实现细节。可以安全地依赖的是,NSNotificationCenter同步发送其通知(以下讨论的特定情况除外),因此通过添加另一个观察者并从那里调度块,您可以更安全
您可以这样做(假设为圆弧):
由于该通知将在发布队列上同步传递,因此您可以确信,-ihopeyougetthis after you获得通知后将发生通知
,而不管发布通知的线程是什么
请注意,如果X
以异步方式接收通知(例如,通过使用-addObserverForName:object:queue:usingBlock:
订阅通知并通过[NSOperationQueue mainQueue]
),则这将无法保证工作,但这似乎不太可能(而且是可以避免的)安排
__block id token = [[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextObjectsDidChangeNotification object: moc1 queue: nil usingBlock:^(NSNotification *note) {
if (token)
{
id copyOfToken = token; // so it'll be const-copied into the next block, despite token being nilled out
dispatch_async(dispatch_get_main_queue(), ^{
[X iHopeYouGetThisAfterYouGotTheNotification];
[[NSNotificationCenter defaultCenter] removeObserver: copyOfToken];
});
token = nil;
}
}];