如何将未保存的 NSManagedObjectContext 更改从一个上下文合并到另一个上下文?

Posted

技术标签:

【中文标题】如何将未保存的 NSManagedObjectContext 更改从一个上下文合并到另一个上下文?【英文标题】:How to merge unsaved NSManagedObjectContext changes from one context to another? 【发布时间】:2017-01-06 02:13:19 【问题描述】:

我有两个NSManagedObjectContext,一个用于在后台从一个api响应写入数据,另一个是填充一个NSFetchedResultsController,如下:

// moc used to fetch objects via NSFetchedResultsController:

    moc = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
            moc.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy


// moc used when writing data from an api response:

    backgroundMoc = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
            moc.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy

有些对象暂时存储在后台 moc 中(无需调用 .save()),我需要将这些更改合并到主 moc,以便我的 NSFetchedResultsController 可以访问它。

我尝试订阅NSManagedObjectContextDidSaveNotification,但只有在我调用backgroundMoc.save() 时才会受到影响,我试图避免这种情况,因为我的backgroundMoc 中的对象有未保存的更改。

最好的方法是什么?

【问题讨论】:

【参考方案1】:

使用NSPersistentContainer 并在viewContext 上设置automaticallyMergesChangesFromParent,您应该将其用于获取控制器,然后使用newBackgroundContext 进行后台工作。当后台上下文保存时,它的持久协调器(也是viewContext 的父级)通知viewContext,它合并了更改。

请注意,如果您不希望将所有背景对象添加到视图上下文中,那么您可以改为观察通知并过滤您需要的对象,例如当前视图控制器正在或应该显示的对象。

这超出了这个问题的范围,但如果您的背景上下文在另一个进程中,例如扩展,然后您可以使用持久历史来查询更改的内容并将其添加到视图上下文中。

太多的开发人员滥用了从未设计用于后台操作的父上下文,因此 Apple 最终介入并添加了此内容。

【讨论】:

【参考方案2】:

对此没有内置机制。当您在一个上下文中有未保存的更改时,这些更改仅存在于该上下文中。其他上下文看不到它们,因此它们无法获取它们包含的信息。如果您不想保存更改,您唯一的选择是在其他上下文中再次进行相同的更改。也就是说,无论你在上下文 A 中做了什么,在上下文 B 中再做一次,所以它有相同的变化。

【讨论】:

以上是关于如何将未保存的 NSManagedObjectContext 更改从一个上下文合并到另一个上下文?的主要内容,如果未能解决你的问题,请参考以下文章

如何将未更改的值发送到 gwt RequestFactory 中的服务器?

SQLAlchemy 如何将未映射的 COUNT(*) 作为查询的结果?

如何将未扭曲图像的点投影到扭曲图像?

如何将未压缩的文件夹视为压缩文件?

如何将未暂存的文件移动到未跟踪的位置?

如何使用 golang 将未编组的 JSON 连接到 HTML 页面?