Ios 多次调用NSManagedObjectContextDidSaveNotification
嗨,我有一个FriendsViewController,在那里我可以显示从coreData获取的朋友记录。我有另一个视图控制器AddFriendViewController,它由FriendsViewController提供,用于添加新朋友,并将上下文保存在其中。我正在FriendsViewController中收听共享MOC上的更改通知Ios 多次调用NSManagedObjectContextDidSaveNotification,ios,core-data,ios9,Ios,Core Data,Ios9,嗨,我有一个FriendsViewController,在那里我可以显示从coreData获取的朋友记录。我有另一个视图控制器AddFriendViewController,它由FriendsViewController提供,用于添加新朋友,并将上下文保存在其中。我正在FriendsViewController中收听共享MOC上的更改通知 [[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectConte
[[NSNotificationCenter defaultCenter]
addObserverForName:NSManagedObjectContextDidSaveNotification
object:appdelegate.context queue:nil
usingBlock:^(NSNotification * _Nonnull note) {
NSLog(@"Re-Fetch Whole Friends Array from core data and Sort it with UILocalizedIndexedCollation and reloadData into table");
}];
在AddFriendsViewController中,只需创建一个friend对象,然后
Friend *friend= [NSEntityDescription
insertNewObjectForEntityForName:@"Friend"
inManagedObjectContext:appdelegate.context];
friend.name=nameTextfield.text;
[appdelegate.context save:&error];
[self.navigationController popViewControllerAnimated:YES];
现在,当我从AddFriendViewController对上下文执行保存时,FriendsViewController中的上述块被触发几次,而不是一次,这会导致更多处理,因为从核心数据重新获取整个数据。我无法使用“获取结果”控制器,因为我正在使用UILocalizedIndexedCollation将数组排序到节中。所以我的问题是,为什么它被称为两次,有时甚至三次?或者有其他选择吗?只有您知道何时需要激活通知观察者 然而,两种常见的范例是: 如果您希望在视图控制器的生命周期内随时收到通知,则可以在
viewDidLoad
中注册观察者,并在dealloc
中删除观察者
如果希望在视图处于活动状态时随时收到通知,请在视图中注册观察者将出现,并在视图中删除观察者将消失
编辑
我使用此语句删除所有条目[[NSNotificationCenter]
defaultCenter]removeObserver:self];而且还是一样的
行为。然后我使用addObserver:selector:name:object:method
这起作用了。但是为什么另一个没有被移除呢阿萨杜拉·阿里
这是因为您添加了一个基于块的观察者,它返回一个观察者对象。您删除它返回给您的对象。您确实应该阅读您使用的每个方法的文档
如果使用块观察者方法,则添加/删除将如下所示
id observer = [[NSNotificationCenter defaultCenter]
addObserverForName:SomeNotification
object:objectBeingObserved
queue:nil
usingBlock:^(NSNotification *note) {
// Do something
}];
[[NSNotificationCenter defaultCenter] removeObserver:observer];
如果使用选择器观察者方法,则需要删除为add调用提供的观察者
[[NSNotificationCenter defaultCenter]
addObserver:someObject
selector:@selector(notificationHandler:)
name:SomeNotification
object:objectBeingObserved];
[[NSNotificationCenter defaultCenter]
removeObserver:someObject
name:SomeNotification
object:objectBeingObserved];
首先,我强烈建议使用NSFetchedResultsController
,而不是构建自己的观察者
第二,听起来您多次添加观察者。您应该在-viewDidLoad
中添加它,并在-dealoc
中删除它
同样,NSFetchedResultsController是一个更好的解决方案。您将获得更好的性能,并避免像现在这样重新蚀刻。您必须摆脱观察者(正如其他人已经在这里说明的那样)。最简单的方法是使用一个“一次性观察者”,它在激活时会自动移除。在您的示例代码中,这类似于:
id __block observer;
observer = [[NSNotificationCenter defaultCenter]
addObserverForName:NSManagedObjectContextDidSaveNotification
object:[PubStore sharedStore].managedObjectContext queue:nil
usingBlock:^(NSNotification * _Nonnull notification) {
[[NSNotificationCenter defaultCenter] removeObserver:observer];
NSLog(@"Re-Fetch Whole Friends Array from core data and Sort it with UILocalizedIndexedCollation and reloadData into table");
}];
请注意,必须将观察者存储在\u块
变量中,才能在触发观察者时执行的块内使用它 您是否碰巧使用了多个托管对象上下文,它们之间有父/子关系?我已经发现我必须删除此观察者我正在didLoad中添加此观察者,但不知道从何处删除它?另外,我在堆栈中的该视图控制器后面有一个视图控制器,因此每次我返回并再次推送到该视图时,它都会添加另一个观察者。我希望使用NSFetchedResultsController,就像我在其他TableViewController或ViewController中使用它一样。但是我不能在这里使用它,因为我必须支持不同语言的名称(在我的例子中是中文、英文)才能用SectionIndexTitle进行排序。我已经尽力了,但最终还是这样做了。如果您能建议使用FRC进行中文、英文排序的其他方法,我们将不胜感激。Ref:我注意到使用此方法添加的观察者addObserverForName:object:queue:usingBlock:未在dealloc方法中删除。block观察者有一些问题。我不建议使用它。还有其他问题吗。因为jodyI在下面澄清了我面对的问题,我注意到使用此方法添加的ObserverForName:object:queue:usingBlock:在dealloc方法中未被删除。我使用此语句删除所有条目[[NSNotificationCenter defaultCenter]removeObserver:self];它仍然表现出同样的行为。然后我使用了addObserver:selector:name:object:method,这很有效。但是为什么另一个没有被删除呢?是的,这一个总结了。谢谢