在我的应用程序中,我有一个NSFetchedResultsController
可以在UITableView中加载Core Data对象。与此FRC关联的提取请求使用可用于viewContext
(iOS10)的新NSPersistentContainer
属性。
当我选择一个单元格时,我将Core Data对象传递给新的ViewController。此新的VC仍使用viewContext。通过此ViewController,我可以从模态显示的ViewControllers中更新Core Data对象。为此,我将newBackgroundContext()
用于模式ViewController。我可以保存更新的核心数据对象而没有任何问题。
问题在于,FRC不会自动从后台上下文中使用更新的核心数据对象进行更新。好像viewContext没有接收并处理Core Data对象更新。
如果将viewContext(应用程序范围)的automaticallyMergesChangesFromParent
设置为true,则保存背景上下文时,FRC将获取更新的Core Data对象。据我了解,viewContext应该自动管理数据合并。该文档通过以下方式描述viewContext:“此上下文配置为具有代际性,并自动使用其他上下文的保存通知。”
您能否阐明如何使用NSFetchedResultsController处理不同的上下文?
您看到的是正确的行为。如果您希望viewContext自动从其他上下文中拾取更改,包括newBackgroundContext()
创建的更改,则必须将automaticallyMergesChangesFromParent
设置为true
。
我同意文档在这一点上令人困惑,“ ...并自动使用来自其他上下文的保存通知。”
自动合并来自父项的更改,像这样在viewContext上进行设置:
persistentContainer.viewContext.automaticallyMergesChangesFromParent = true
我还没有直接遇到这个问题,但是如果newBackgroundContext实际上位于viewContext下,您的问题让我感到奇怪,因为从新上下文中进行的任何保存都只会更新viewContext,这也必须自己保存以获取对持久性存储所做的更改(您说这是正确发生的)。基于这种怀疑,我看了苹果说的开发人员文档:
调用此方法(newBackgroundContext())使持久性容器创建并返回一个新的NSManagedObjectContext,并将concurrencyType设置为privateQueueConcurrencyType。此新上下文将直接与NSPersistentStoreCoordinator关联,并设置为自动使用NSManagedObjectContextDidSave广播。
因此,它不会与viewContext处于父子关系。根据指导,似乎旧的更改将通知新上下文,反之亦然,因此,当新的上下文更改时,您必须对viewContext进行刷新,如果可以的话,可以通过编程方式进行在您的代码中跟踪它,或者使用NSManagedObjectsContext中的更改通知之一来触发操作。
对我不起作用,所以我从中更改了保存块
self.persistentContainer.performBackgroundTask { (context) ... }
to
self.persistentContainer.newBackgroundContext().performAndWait { ... }
并且科西斯将true设置为automaticallyMergesChangesFromParent
以使自动合并生效。
lazy var viewContext: NSManagedObjectContext = {
self.persistentContainer.viewContext.automaticallyMergesChangesFromParent = true
self.presistentContainer.viewContext.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump
return self.persistentContainer.viewContext
}()
我不知道为什么context
中的performBackgroundTask
没有合并到viewContext
。