两个不同视图中的NSManagedObjectContextObjectsDidChangeNotification问题

时间:2011-05-10 18:15:34

标签: notifications nsfetchedresultscontroller multiple-views

大家晚上好,

在解释我的问题之前,我应该首先给你一些关于我的项目的解释:

我有一个简单的Coredata模型,其中一个实体称为“对话”,另一个实体称为“消息”。基本上,我需要重现iPhone短信应用程序。

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

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

如您所见,我的模型很容易理解。几周前我问了一些关于如何完全实现这些视图的帮助(即在视图中使用NSFetchedResultsController(FRC),而不是在this post上显示来自特定对话的消息。

所以我做的是我在每个视图中使用一个FRC。另一个线程是不时更新我的​​模型。为了通知我的观点我的模型发生了变化,我在第二个帖子中使用了这个:

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

mergeChanges:function正在执行此操作:

- (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的属性,所以当它变为poped时,它的值应为零。 (我认为)。

我的问题是:为什么这个被发送到一个没有显示的视图?我无法在任何地方看到它在调试器中的价值。我试图使它成为视图的属性,然后在回到ConversationVC时为它分配“nil”,但后来我收到一个SIGBRT错误,说通知被发送到一个解除分配的变量(这是合乎逻辑的)。 />  我真的需要将它发送到当前显示的视图。 你有什么主意吗 ?

非常感谢

2 个答案:

答案 0 :(得分:2)

好的......让我问一个问题:视图是否显示然后隐藏 - 即你是否忘记告诉它停止观察通知?

答案 1 :(得分:1)

这可能对某些人有所帮助:

对于那个问题,我没有忘记调用[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绑定更改的数据时,将以某种方式调用委托,并调用这三种方法。

我做的是:

- (void) viewDidDisappear {
    self.fetchedResultsController = nil; // using the property !
}
像这样,如果它被调用,消息将被发送到nil,这是被授权的,而不是被解除分配的实例变量。