Проблема с NSManagedObjectContextObjectsDidChangeNotification в двух разных представлениях - PullRequest
1 голос
/ 10 мая 2011

Добрый вечер всем,

Прежде чем объяснить мою проблему, я должен дать вам некоторое объяснение моего проекта:

У меня есть простая модель Coredata с одной сущностью, называемой «Разговор», а другая - «Сообщение». По сути, мне нужно как-то воспроизвести смс-приложение для iPhone.

Conversation{  
    messages<-->>Message.conversation  
}  

Message{  
    conversation<<-->Conversation.messages  
}    

Как видите, мою модель легко понять. Несколько недель назад я попросил некоторой помощи о том, как полностью реализовать эти представления (т. Е. Использовать NSFetchedResultsController (FRC) или нет в представлении, отображающем сообщения из определенного разговора на этой записи .

Итак, что я сделал, так это то, что я использую один FRC в каждом представлении. Другой поток время от времени обновляет мою модель. Чтобы уведомить мои взгляды, что моя модель изменилась, я использовал это во второй теме:

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];  
[nc addObserver:self
       selector:@selector(mergeChanges:)
           name:NSManagedObjectContextDidSaveNotification
         object:_context];  

И функция mergeChanges: делает это:

- (void)mergeChanges:(NSNotification *)notification {  
AppDelegate *appDel = (AppDelegate*)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *mainContext = [appDel managedObjectContext];

// Merge changes into the main context on the main thread
[mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
                              withObject:notification
                           waitUntilDone:YES];  
}  

Мне показалось, что этот код отлично работает, потому что в обоих viewController (давайте назовем их ConversationVC (где перечислены все разговоры) и MessageVC (где перечислены все сообщения из определенных бесед)) я использовал:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller;
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath;
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller;  

Моя проблема, однако, заключается в следующем:
Когда я вставляю новые сообщения во второй поток и контекст сохраняется, уведомление отправляется обоим представлениям, даже если MessageVC не отображается. Это не свойство моего ConversationVC, поэтому, когда оно появляется, его значение должно быть равно нулю. (Я думаю).

Мой вопрос: почему это отправляется в представление, которое не отображается? Я не вижу его значение в отладчике нигде. Я попытался сделать его свойством представления, а затем присвоил ему значение «nil» при возвращении в ConversationVC, но затем я получаю ошибку SIGBRT, говорящую, что уведомление было отправлено в освобожденную переменную (что было логично).
Мне действительно нужно, чтобы оно было отправлено только в настоящее время отображается. Есть ли у вас какие-либо идеи ?

Большое спасибо

Ответы [ 2 ]

2 голосов
/ 10 мая 2011

Хорошо ... позвольте мне задать один вопрос: отображается ли представление и затем скрывается - т.е. вы забыли сообщить об этом, чтобы СТОП наблюдал за уведомлениями?

1 голос
/ 17 октября 2011

Это может помочь некоторым людям:

Для этой проблемы я не забыл вызвать [NSNotificationCenter removeObserver:], потому что метод, о котором я говорил, где:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller;
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath;
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller;  

Этиметоды принадлежат NSFetchedResultsControllerDelegate.По сути, всякий раз, когда вносятся изменения в CoreData, и когда ваш NSFetchedResultsController связывается с измененными данными, делегат вызывается как-то и вызывает эти три метода.1010 * вот так, если он вызывается, сообщение будет отправлено nil, который авторизован, а не освобожденной переменной экземпляра.

...