1

各位晚上好,

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

我有一个简单的 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 时为其分配“nil”,但随后我收到一个 SIGBRT 错误,指出通知已发送到已释放的变量(这是合乎逻辑的)。
我真的需要它只发送到当前显示的视图。你有什么主意吗 ?

非常感谢

4

2 回答 2

2

Okay... let me ask one question: does the view get displayed and THEN hidden - i.e. did you forget to tell it to STOP observing the notifications?

于 2011-05-10T18:30:55.150 回答
1

这可能会帮助一些人:

对于那个问题,我没有忘记调用 [NSNotificationCenter removeObserver:] 因为我所说的方法 where :

- (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,而不是被释放的实例变量。

于 2011-10-17T05:23:05.967 回答