两个私有队列上下文之间的 mergeChangesFromContextDidSaveNotification
Posted
技术标签:
【中文标题】两个私有队列上下文之间的 mergeChangesFromContextDidSaveNotification【英文标题】:mergeChangesFromContextDidSaveNotification between two private queue contexts 【发布时间】:2015-07-21 10:08:35 【问题描述】:在我的应用程序中,我调用服务器 API 来获取用户列表。我在带有 NSFetchedResultsController 的 UITableView 中显示这些用户。一些用户与当前连接的用户保持联系,而其他用户则没有。首先,我向您展示我的核心数据堆栈(使用 MagicalRecord):
我设法使用usersContext
向所有用户(联系人而不是联系人)显示我从网络服务创建/更新/删除所有用户的位置。任何时候我保存 tableView 都会更新。这工作正常。
但我想将 usersContext 合并到 contactsContext 以便仅将联系人保存在商店中,以便在下次启动应用程序时直接显示它们。我的问题来了。当我contactsContext mergeChangesFromContextDidSaveNotification
时,没有用户被保存(当然还有联系人)。也许我的核心数据堆栈或我的代码是错误的:
// init
- (void)configureContactsStack
_contactsContext = [NSManagedObjectContext MR_contextWithStoreCoordinator:[NSPersistentStoreCoordinator MR_defaultStoreCoordinator]];
[_contactsContext MR_setWorkingName:@"Contacts context"];
_usersContext = [NSManagedObjectContext MR_contextWithParent:[NSManagedObjectContext MR_defaultContext]];
[_usersContext MR_setWorkingName:@"Users context"];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(usersContextDidSave:) name:NSManagedObjectContextDidSaveNotification object:_usersContext];
- (void)getAllUsers
// async server call with main thread callback :
[self.usersContext performBlock:^
// ... create/update/delete users in usersContext with server objects
[self.usersContext MR_saveOnlySelfAndWait]; // will call usersContextDidSave:
];
// end of server callback
- (void)usersContextDidSave:(NSNotification *)notification
if (notification.object == self.usersContext)
[self.contactsContext performBlock:^
[self.contactsContext mergeChangesFromContextDidSaveNotification:notification];
// delete all users not contacts from contactsContext
[Users deleteAllMatchingPredicate:[NSPredicate predicateWithFormat:@"contact != 1"] inContext:self.contactsContext];
[self.contactsContext MR_saveToPersistentStoreWithCompletion:nil];
];
【问题讨论】:
【参考方案1】:不要合并同级上下文。那会给你带来麻烦。 NSManagedObjectContext
的实例很便宜,当您使用私有队列上下文时,它们打算在一次使用后被丢弃。使用它们,扔掉它们,为下一个需要完成的工作创建一个新的。
无需合并更改通知。
【讨论】:
所以每次调用服务器时,我都会创建 2 个上下文?一种用于所有用户创建/更新/删除以显示,另一种仅用于保存联系人? 为什么需要两个?您是否保存到超过堆栈?如果不是,那么每个数据调用一个私有上下文应该绰绰有余。 如果我使用一个上下文,它将更新所有用户的 UI。然后,如果我删除所有不是联系人的用户(仅保留联系人)并保存,它们将从 UI 中消失。也许我需要一种完全不同的方法来完成我想做的事情...... 我会建议一种不同的方法。如果您希望您的 UI 显示一个子集,那么它应该过滤数据,您正在使用/滥用可能会消失的父/子上下文的怪癖。最好进行数据级过滤和单个导入上下文(无论如何一次一个)。您的应用会更快乐、更健壮。 好的我现在意识到我的方法太复杂了(也许我太聪明了:))。我将在数据级别进行过滤,一切都会完美运行。感谢您的所有提示。问候以上是关于两个私有队列上下文之间的 mergeChangesFromContextDidSaveNotification的主要内容,如果未能解决你的问题,请参考以下文章
托管对象上下文保存和 refreshObject:mergeChanges 有啥区别:
调用 refreshObject(object, mergeChanges: NO) 时核心数据内存峰值
CoreData 和 NSManagedObject 上下文 - 私有与主