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

时间:2016-09-06 12:10:11

标签: ios core-data ios10 nsfetchedresultscontroller nsmanagedobjectcontext

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

当我选择一个单元格时,我将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处理不同的上下文?

4 个答案:

答案 0 :(得分:30)

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

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

答案 1 :(得分:8)

自动将来自父需求的更改合并到viewContext上,如下所示:

persistentContainer.viewContext.automaticallyMergesChangesFromParent = true

答案 2 :(得分:6)

我还没有直接遇到这个问题,但是如果newBackgroundContext实际上是在viewContext下分层的,那么你的问题就像奇怪一样,因为来自新上下文的任何保存只会更新viewContext,这也是必须要做的它自己保存以获取持久存储的更改(您说这是正确发生的)。基于这种怀疑,我查看了Apple所说的开发人员文档:

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

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

答案 3 :(得分:0)

不适用于我,所以我将保存块从更改为

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

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

并且要正确地设置automaticallyMergesChangesFromParent为使自动合并起作用。

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

我不知道为什么context中的performBackgroundTask没有合并到viewContext