NSManagedObjectContext запазване/сливане върху множество нишки чрез проблем с центъра за уведомяване

Това е по-скоро защо това работи и това не е въпрос...

Използвам 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], но изглежда не мога да разбера защо би накарал нишката да спре. Успях да натисна продължи в дебъгера и просто да продължа... но не разбирам защо функционираше по този начин.

Предполагам, че правя нещо нередно и се притеснявам, че новият ми начин може да е просто хак.

Благодаря за помощта!


person Derek    schedule 04.05.2011    source източник


Отговори (3)


Мисля, че първият работи поради асинхронното изпращане. Без това центърът за уведомяване ще спре, докато някое конкретно известие завърши. Проблемът, който сте получавали, звучи като типичен застой, при който кодът просто спира без грешка, докато в крайна сметка програмата за отстраняване на грешки изтече.

person TechZen    schedule 05.05.2011

Не съм сигурен дали това помага, но когато имате нула за опашката, опитайте да използвате обща опашка. Разгледайте шаблона за дизайн на рецепционистката в документите на Apple.

 NSOperationQueue *queue = [[NSOperationQueue alloc] init];
person Arvin    schedule 07.12.2011

Обединяването във вашия първи примерен код е правилно изпратено в основната нишка, която най-вероятно е и нишката, в която е създаден moc.

Във втората ви проба сливането ще бъде изпълнено във фонова нишка, ако известието е било издадено в bg нишка (обратните извиквания за известия винаги се извикват в същата нишка, където е публикувано известието).

Между другото, вместо да използвам основната опашка, сега бих предпочел да използвам собствения performBlock: метод на NSManagedObjectContext (>= 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];
    }];
}];
person manmal    schedule 15.10.2012