天天看点

iOS 10 中的 NSPersistentContainer

<b>本文讲的是iOS 10 中的 NSPersistentContainer,</b>

<b></b>

多年来,在尝试了很多种 <code>Core Data stack</code> 之后,我们选定了两个简单的 <code>stack</code>,融合成一个使用。让我们仔细看一下这些关键组件并开始连接使用他们。完整版本的 <code>Github</code> 链接在引用中能找到。代码已经适配到 <code>Swift 3</code> 和 <code>Xcode 8</code>。

上面是啥?且容我慢慢道来。

在初始化的时候,我们订阅了从主线程和后台线程 <code>NSMagedObjectContext</code> 发送来的通知。

获取文档路径 <code>NSURL</code> 的 <code>getter</code>。<code>NSPersistentStoreCoordinator</code> 使用它在给定的位置创建 <code>NSPersistentStore</code>。

和文件目录相似,他获得 <code>NSManagedObjectModel</code> 的 <code>getter</code> 方法,用它来初始化有我们模型的<code>NSPersistentStoreCoordinator</code>。

这就是这些神奇的代码干的事情。首先,我们创建有模型的 <code>NSPersistentStoreCoordinator</code>。之后,我们获取我们文档目录的 <code>url</code>。最后,我们在这些文档目录内为某些类型的 <code>NSPersistentStoreCoordinator</code> 增加一个持久化的存储。

我们在一个私有队列里创建一个'后台' <code>NSManagedObjectContext</code> 并且把它绑定到 <code>NSPersistentStoreCoordinator</code>。这个<code>context</code> 被用于执行同步和写操作。

我们在主队列中创建一个'视图' <code>NSManagedObjectContext</code>并且把它绑定到我们的 <code>NSPersistentStoreCoordinator</code>。这个<code>context</code> 被用于获取显示在 <code>UI</code> 上的数据。

这个 <code>stack</code> 使用了稳定、成熟的融合过的 <code>contexts</code>,它被保存的 <code>notifications</code> 驱动。在这些方法中,我们执行这个融合。

iOS 10 给我们提供了 <code>NSPersistentContainer</code>。它意图简化代码并且为我们解决负担。它能做到么?让我展示给你我们基于<code>NSPersistentContainer</code> 重建 <code>CoreData stack</code> 。 一个完整的例子:

实际上这个更简短。但是之前版本的代码发生了什么?

简单的答案是,<code>NSPersistentContainer</code> 已可以为我们代劳。对于一个博客文章的解释,这肯定不够 

iOS 10 中的 NSPersistentContainer

 。还是容我慢慢道来。

这里,我们能看到 <code>NSPersistentContainer</code> 的能力。它完成了之前 <code>stack</code> 内#2, #3, #4, #5, #6 的工作,并一定程度上把我们从 #1 和 #7 中的工作中解放出来。

怎么做到的?

首先,它通过一个名字来初始化,这个名字被用于在文档目录中查找一个模型并且用相同的名字创建一个存储器。这是一个快捷初始器。你也可以使用完整的版本,手动地传递你的模型。

之后,在调用 <code>loadPersistentStores</code> 方法之前,你还有时间来进一步配置你的容器,例如,使用<code>NSPersistentStoreDescription</code>。我们使用一个默认的 <code>SQLite</code> 数据库,所以我们装载自己的永久存储器并且确保错误处理。

实际上这只是一个封装器。已经通过 <code>NSPersistentContainer</code> 为我们创建了 <code>viewContext</code>。而且,它已经被配置成可以接收从其他的 <code>contexts</code> 来的保存通知。引用自 <code>Apple</code> 公司:

这个被管理的 <code>context</code> 对象与主队列有关。(只读)... 这个 <code>context</code> 是被配置成可持续的,并且从其他 <code>contexts</code> 处理保存的通知。

<code>NSpersistentContainer</code> 也给予了我们一个工厂方法,它用来创建多个私有队列的 <code>contexts</code>。我们为了复杂的同步目的,在这里仅使用一个,常见的后台 <code>context</code>。由工厂方法创建出的 <code>Contexts</code> 也被设定成可自动地接收和处理<code>NSManagedObjectContextDidSave</code> 的广播消息。 这是可选项。

<code>NSPersistentContainer</code> 在后台(详情可见 #5)为运行 <code>Core Data stack</code> 暴露了一个方法。我们非常喜欢这个 <code>API</code> 的命名,所以我们也为 <code>viewContext</code> 创建了类似的封装器。

正如上文提到的,这仅是一个有关 <code>performBackgroundTask</code> 方法的封装器,它是 <code>NSPersistentContainer</code> 中的一个方法。每一次它调用一个新的 <code>context</code>, <code>parivateQueueConcurrencyType</code> 也被创建。

有一些可选项。

首先,确保查阅了完整的参考资料,并且在寻找你所需要的属性或者方法。我们已经涵盖了两个初始化器,一个仅需要字符串名和完整采用 <code>NSManagedObjectModel</code> 的快捷方法。

之后,你可以调查扩展或者子类。举个例子,在我们其中一个项目中,我们在核心程序和扩展程序之间共享了一个 <code>Core Data stack</code>。它不得不落地在一个 App 共享组群空间中,并且 <code>NSPersistentContainer</code> 默认的文档目录已经不再为我们所用。

幸运的是,通过一个轻量的子类 <code>NSPersistentContainer</code>,我们又满血复活了,并且能继续使用那些容器类带来的好处。

我希望你们喜欢这篇有关 <code>NSPersistentContainer</code> 的简短精干的文章,并且我们也希望看到你们是如何通过这些在 <code>Core Data</code> 框架上的改进来演进你们的 <code>Core Data stack</code>。

稍等一下... 啊?还有其他的改变么?

是的,当然有。最佳的方法是通过 <code>Apple</code> 公司的官方推文 'Core Data 在 iOS 10 上的新特性'。这些改变从并发、<code>context</code> 版本、请求获取、自动融合来自父 <code>context</code> 变化等开始,以在 <code>macOS 10.12</code> 中的 <code>NSFetchResultsController</code> 结束。

<b>原文发布时间为:2016年10月28日</b>

<b>本文来自云栖社区合作伙伴掘金,了解相关信息可以关注掘金网站。</b>