两个私有队列上下文之间的 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 上下文 - 私有与主

CoreData:带有子主上下文的私有上下文 - FetchedResultsController 未获得更新

在私有/后台队列上创建 NSManagedObjectContext:怎么办?