【问题标题】:Core Data viewContext not receiving updates from newBackgroundContext() with NSFetchedResultsController核心数据 viewContext 未使用 NSFetchedResultsController 从 newBackgroundContext() 接收更新
【发布时间】:2017-01-13 21:28:46
【问题描述】:

在我的应用程序中,我有一个NSFetchedResultsController 在 UITableView 中加载核心数据对象。 与此 FRC 关联的提取请求使用可用于 NSPersistentContainer (iOS10) 的新 viewContext 属性。

当我选择一个单元格时,我将 Core Data 对象传递给一个新的 ViewController。这个新的 VC 仍然使用 viewContext。 通过这个 ViewController,我可以从模态显示的 ViewController 中更新 Core Data 对象。为此,我将newBackgroundContext() 用于模态视图控制器。我可以毫无问题地保存更新的 Core Data 对象。

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

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

您能否阐明如何使用 NSFetchedResultsController 处理不同的上下文?

【问题讨论】:

    标签: ios core-data ios10 nsfetchedresultscontroller nsmanagedobjectcontext


    【解决方案1】:

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

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

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

    【讨论】:

    • .automaticallyMergesChangesFromParent 的文档(在 NSManagedObjectContext.h 中)说:“上下文是否自动合并保存到其协调器或父上下文的更改。当上下文固定到非不支持当前查询生成”。因此,“商店协调员”似乎涵盖了没有父母的情况。 .viewCoordinator 和 .newBackgroundContext 共享同一个存储协调器(我刚刚检查过)。所以设置 .automaticallyMergesChangesFromParent 会导致预期的行为。
    【解决方案2】:

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

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

    【讨论】:

    【解决方案3】:

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

    persistentContainer.viewContext.automaticallyMergesChangesFromParent = true
    

    【讨论】:

      【解决方案4】:

      不适合我,所以我从

      更改了保存块
      self.persistentContainer.performBackgroundTask { (context) ... }
      

      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
      }()
      

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

      【讨论】:

        猜你喜欢
        • 2019-11-12
        • 2012-02-17
        • 1970-01-01
        • 1970-01-01
        • 2012-06-01
        • 2011-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多