NSManagedObjectContext сохранение / объединение в нескольких потоках через проблему центра уведомлений - PullRequest
0 голосов
/ 05 мая 2011

Это больше, почему это работает, и это не такой вопрос ...

Я использую 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], но я не могу понять, почему это заставит поток приостановиться.Мне удалось нажать «Продолжить» в отладчике и просто двигаться дальше ... но я не понимаю, почему он работал таким образом.

Я предполагаю, что я делаю что-то не так, и я волнуюсь, что мой новый способможет быть просто взломать.

Спасибо за помощь!

Ответы [ 3 ]

1 голос
/ 05 мая 2011

Я думаю, что первый работает из-за асинхронной отправки. Без этого центр уведомлений будет приостановлен, пока не завершится какое-либо конкретное уведомление. Проблема, которую вы получили, звучит как типичная остановка, в которой код просто останавливается без ошибок до тех пор, пока время отладчика не истечет.

0 голосов
/ 15 октября 2012

Слияние в вашем первом примере кода правильно отправлено в основной поток, который, скорее всего, также является потоком, в котором был создан moc.

Во втором примере слияние будет выполняться в фоновом потоке, если уведомление было отправлено в потоке bg (обратные вызовы уведомлений всегда вызываются в том же потоке, в котором размещено уведомление).

Кстати, вместо использования основной очереди, я бы предпочел использовать собственный метод NSManagedObjectContext performBlock: (> = iOS 5). На iOS5 с ARC этот код сводится к:

__weak typeof(self) weakSelf = self;
[[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
    [weakSelf.moc performBlock:^{
        [weakSelf.moc mergeChangesFromContextDidSaveNotification:note];
    }];
}];
0 голосов
/ 07 декабря 2011

Не уверен, поможет ли это, но там, где у вас нет nil, попробуйте использовать общую очередь.Взгляните на шаблон оформления регистрации в документах Apple.

 NSOperationQueue *queue = [[NSOperationQueue alloc] init];
...