【问题标题】:Core Data API usage best patterns in iOS 10iOS 10 中的 Core Data API 使用最佳模式
【发布时间】:2017-05-05 15:45:59
【问题描述】:

我上次在寻找一些与 iOS 10 中的核心数据相关的书籍,特别是涵盖诸如查询生成、NSPersistentContainer、如何使用他们的新并发模型在新 API 中设置我的上下文层次结构等主题。

我读到现在每个上下文都应该将它们的父级设置为nil,最好的方法是将每个上下文直接连接到持久故事协调器。如果我们的目标是在我们的应用程序中响应 UI,则无需在上下文之间设置父/子关系。我有以下问题:

  1. 每次我需要在后台执行某项任务时,我是否需要使用container.newBackgroundContext() 方法来创建上下文,或者我应该创建一个上下文并将其存储在某处并重复使用以获得更好的性能?我可以创建多少上下文?背景上下文的最佳数量是多少?
  2. 我是否需要将 container.viewContext 父级设置为从 container.newBackgroundContext() 创建的一些私有上下文?
  3. 创建一个后台任务的最佳方法是更新非主队列上后台线程中的一些数据并通知此主viewContext
  4. 通知后台上下文有关用户在 UI 中主要 viewContext 中引入的模型更改的最佳方式是什么?
  5. 您是否知道一些涵盖这些主题的书籍,包括 iOS 10 中的架构和并发更改?

【问题讨论】:

  • this course 有两个讲座涵盖核心数据。这是基础知识,但我认为它可以作为一个有用的起点。

标签: ios core-data swift3 ios10


【解决方案1】:
  1. 您通常不需要这样做。为特定任务创建背景上下文,然后将其拆除。或者,NSPersistentContainer 有一个方法 performBackgroundTask():只需将一个块传递给它,它就会为您创建一个新的私有上下文来运行这个块。
  2. 不。 NSPersistentContainer 为您处理。
  3. 如果您观察viewContext 的更改,那么只要您在任何后台队列中进行保存,此更改就会渗透。或者,使用NSFetchResultsController,它有很多可以帮助您响应更改的委托方法。
  4. 您不需要这样做。只需在私有队列中做您需要做的事情,您的合并策略将决定发生冲突时会发生什么。
  5. 不幸的是,这些更改仍然相对较新。阅读NSPersistentContainer 的文档以及What's New in Core Data 页面。

【讨论】:

  • 感谢您的回答。我需要澄清一些事情。 3 不设置automaticallyMergesChangesFromParent = true viewContext 是否会将私有上下文的更改推送到viewContext? 4 呢?当我保存 viewContext 时,我的私有上下文是否会在不设置私有上下文automaticallyMergesChangesFromParent = true 的情况下进行此更改?
  • 不,但是您为什么对能够合并来自父级的更改的私有上下文感兴趣?此属性在创建子 mainQueue 上下文时更有用,您希望在其中查看对 viewContext 的主要更改。
  • 我的用例场景是我有后台任务正在从后端搜索一些数据。搜索条件存储在本地数据库中,因此当触发任务时,会根据此存储的数据创建查询并发出请求。因此,如果用户在 UI 中修改此搜索条件,我的后台任务需要查看此更改并根据用户设置的新条件准备请求。另一方面,这个后台任务是导入一些 UI 应该能够显示的数据。
  • 对于#4:将viewContext 视为只读(正如文档所说的那样),并且只能使用performBackgroundTask 编写。 performBackgroundTask 内部有一个队列,因此一次只发生一次写入。如果你这样做了,就不会有合并冲突,也不需要 mergePolicy。
  • @JonRose 您关于不使用viewContext 保存的评论不准确。 viewContext 属性在文档中被标记为“(只读)”,因为它没有设置器。这与其他NSPersistentContainer“(只读)”属性(例如namemanagedObjectModel)的其余文档一致。
【解决方案2】:

如果您在任何上下文中将 automaticallyMergesChangesFromParent 设置为 true,它将合并来自任何父上下文的更改。在 iOS 10 中,NSPersistentContainer 创建的任何上下文都将容器的 NSPersistentStoreCoordinator 作为父级。效果是,如果您在 viewContext 上将此设置为 true,则保存在任何 newBackgroundContext 上的更改将自动合并,反之亦然。

【讨论】:

  • 有什么理由不使用这个功能吗?默认为 false 是因为向后兼容还是出于其他原因?
  • 好吧,如果您希望您的上下文被隔离,您可能不希望更改自动合并。或者,如果您想控制合并,您可以编写自己的代码来捕获保存通知并选择是否合并。在大多数情况下,我会将其设置为 true。它也是 iOS 10 中的新功能,因此它们可能默认为 false,因此每个人的行为都不会改变。
  • @Jerry 你的意思是:由 NSPersistentContainer 创建的任何上下文都具有持久存储作为父级?
  • 实际上,我的意思是说他们有NSPersistentStoreCoordinator 作为父母。我会解决的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-04
  • 1970-01-01
  • 1970-01-01
  • 2016-11-20
  • 2012-04-11
  • 2023-04-08
相关资源
最近更新 更多