Core Data viewContext无法使用NSFetchedResultsController从newBackgroundContext()接收更新

问题描述 投票:29回答:4

在我的应用程序中,我有一个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处理不同的上下文?

ios core-data ios10 nsfetchedresultscontroller nsmanagedobjectcontext
4个回答
32
投票

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

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


8
投票

自动合并来自父项的更改,像这样在viewContext上进行设置:

persistentContainer.viewContext.automaticallyMergesChangesFromParent = true

6
投票

我还没有直接遇到这个问题,但是如果newBackgroundContext实际上位于viewContext下,您的问题让我感到奇怪,因为从新上下文中进行的任何保存都只会更新viewContext,这也必须自己保存以获取对持久性存储所做的更改(您说这是正确发生的)。基于这种怀疑,我看了苹果说的开发人员文档:

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

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


0
投票

对我不起作用,所以我从中更改了保存块

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

© www.soinside.com 2019 - 2024. All rights reserved.