0

我的应用程序有一个典型的核心数据后端,其中包含父对象和子NSManagedObjectContext对象。

NSManagedObjectContextmoc1具有.NSMainQueueConcurrencyType

孩子moc2有. NSManagedObjectContext_NSPrivateQueueConcurrencyType

我还有一个观察moc1的对象X。该通知必须到达主线程。NSManagedObjectContextObjectsDidChangeNotification

问题:假设在后台队列上对moc2进行了更改,然后[moc2 save:]被调用。然后,您如何在主线程上向对象 X 发送消息并保证它是在收到之后NSManagedObjectContextObjectsDidChangeNotification而不是之前收到的?是否足以调用:

[moc2 save:NULL];  // causes X to get NSManagedObjectContextObjectsDidChangeNotification for moc1...eventually
dispatch_async(dispatch_get_main_queue(), ^{
    [X iHopeYouGetThisAfterYouGotTheNotification];
};
4

1 回答 1

0

即使您凭经验观察到这样的块是在通知之后执行的,依赖它也会假设未记录的实现细节。可靠的是 NSNotificationCenter 同步发送它的通知(除非下面讨论的一个特定情况),所以通过添加另一个观察者,并从那里分派块,你可以更安全。

您可能会这样做(假设为 ARC):

__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;
    }
}];

由于该通知将在发布队列上同步传递,因此您可以放心-iHopeYouGetThisAfterYouGotTheNotification,无论线程发布通知如何,都会在之后发生。

请注意,如果异步接收通知(例如,通过使用并已通过X订阅通知),那么这将不能保证有效,但这似乎是一种不太可能(且可避免)的安排。-addObserverForName:object:queue:usingBlock:[NSOperationQueue mainQueue]

于 2013-09-28T14:40:32.143 回答