核心数据iOS10:viewContext没有使用NSFetchResultController从newBackgroundContext()接收更新

在我的应用程序中,我有一个NSFetchResultController来加载UITableView中的Core Data对象。 与此FRC关联的获取请求使用可用于NSPersistentContainer (iOS10)的新viewContext属性。

当我选择一个单元格时,我将Core Data对象传递给一个新的ViewController。 这个新的VC仍然使用viewContext。 从这个ViewController,我可以从模态呈现的ViewControllers更新Core Data对象。 为此,我使用newBackgroundContext()作为模态ViewControllers。 我可以毫无问题地保存更新Core Data对象。

问题是FRC不会使用后台上下文中的更新Core Data对象自动更新。 就好像viewContext没有被接收并处理Core Data对象更新一样。

如果我为viewContext(app wide)将automaticallyMergesChangesFromParent设置为true,则FRC在保存背景上下文时获取更新的Core Data对象。 根据我的理解,viewContext应该自动管理数据的合并。 该文档描述了viewContext: “此上下文被配置为世代的,并自动使用来自其他上下文的保存通知。”

你能说明如何使用NSFetchResultController处理不同的上下文吗?

谢谢,阿克塞尔

你看到了正确的行为。 如果希望viewContext自动从其他上下文中获取更改,包括newBackgroundContext()创建的newBackgroundContext() ,则必须将automaticallyMergesChangesFromParent设置为true

我同意文档在这一点上令人困惑, “……并自动使用来自其他上下文的保存通知。”

我没有直接遇到这个,但你的问题让我觉得奇怪,如果newBackgroundContext实际上是在viewContext下分层的,因为来自新上下文的任何保存只会更新viewContext,而viewContext也必须自己保存才能得到对持久性存储的更改(您说正确发生)。 基于这种怀疑,我查看了Apple所说的开发人员文档:

调用此方法(newBackgroundContext())会导致持久容器创建并返回一个新的NSManagedObjectContext,并将concurrencyType设置为privateQueueConcurrencyType。 新上下文将直接NSPersistentStoreCoordinator关联,并设置为自动使用NSManagedObjectContextDidSave广播。

因此,它不会与viewContext处于父子关系中。 根据指导,似乎新的上下文会被旧的通知更改,反之亦然,因此当新的上下文发生更改时,您必须对viewContext进行刷新,如果可以的话,可以通过编程方式执行跟踪代码中的内容,或者使用NSManagedObjectsContext中的某个更改通知来触发操作。

自动合并来自父需求的更改以在viewContext上设置,如下所示:

 persistentContainer.viewContext.automaticallyMergesChangesFromParent = true 

不适合我,所以我改变了保存块

 self.persistentContainer.performBackgroundTask { (context) ... } 

 self.persistentContainer.newBackgroundContext().performAndWait { ... } 

和corse设置为trueMergesChangesFromParent以使自动合并工作。

 lazy var viewContext: NSManagedObjectContext = { self.persistentContainer.viewContext.automaticallyMergesChangesFromParent = true self.presistentContainer.viewContext.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump return self.persistentContainer.viewContext }() 

我不知道为什么performBackgroundTaskcontext没有合并到viewContext