大家晚上好,
在解释我的问题之前,我应该首先给你一些关于我的项目的解释:
我有一个简单的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错误,说通知被发送到一个解除分配的变量(这是合乎逻辑的)。 /> 我真的需要将它发送到当前显示的视图。 你有什么主意吗 ?
非常感谢
答案 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,这是被授权的,而不是被解除分配的实例变量。