[翻译] Core Data 栈
原创作者:Apple
原文链接: Core Data 栈
翻译:Zack
设置 Core Data 栈
设置一个管理和持久你 app 对象的类
预览
在创建一个数据模型文件(正如在“创建数据模型”一章中描述的)后,设置一些配合支持你app 模型层的类。这些类被统一的称为 Core Data 栈。
Persistent_Container.jpeg- NSManagedObjectModel 的实例呈现描述你应用的类型、属性和关系的模型文件。
- NSManagedObjectContext 的实例追踪你应用实例的改变。
- NSPersistentStoreCoordinator 的实例存储和拉取应用实例从数据库中。
- NSPersistentContainer 的实例一次性设置模型, 上下文和数据库协调器的所有。
初始化一个持久容器
通常你初始化 Core Data 在你应用启动的时候,创建一个懒加载的持久化容器去推迟实例化知道在你的应用代理中第一次使用。
如果在你创建一个新 Xcode 项目的时候你选择了 Core Data 复选框,模版自动包含这个设置代码在 Appdelegate.
- 声明一个 NSPersistentContainer 类型的 lazy 变量。
- 创建持久容器实例并且传递数据模型文件名到初始化器中。
- 加载持久化库。这个调用创建一个数据库如果不存在。
class AppDelegate: UIResponder, UIApplicationDelegate {
...
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "DataModel")
container.loadPersistentStores { description, error in
if let error = error {
fatalError("Unable to load persistent stores: \(error)")
}
}
return container
}()
...
}
一旦创建,持久化容器持有 model, context 和 数据库协调器(store coordinator)在它的 managedObjectModel,viewContext, persistentStoreCoordinator 相应的属性中。
你现在能传递容器的引用到你的用户界面。
传递一个持久化容器引用到一个视图控制器
在你应用的根视图控制器中倒入 Core Data 并且创建一个属性去持有持久化容器的引用。
import UIKit
import CoreData
class ViewController: UIViewController {
var container: NSPersistentContainer!
override func viewDidLoad() {
super.viewDidLoad()
guard container != nil else {
fatalError("This view needs a persistent container.")
}
// The persistent container is available.
}
}
返回到你的 app 的 delegate。在 application(_:didFinishLaunchingWithOptions:)
中,强制转换窗口的根视图控制器到你的应用的根视图控制器类型。在这个引用中,设置根视图控制器属性到容器属性。
class AppDelegate: UIResponder, UIApplicationDelegate {
...
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if let rootVC = window?.rootViewController as? ViewController {
rootVC.container = persistentContainer
}
return true
}
...
}
为了传递持久化容器到额外的视图控制器,在每个视图控制器中重复创建容器变量,并且设置它的值在上一个视图控制器的 prepare(for:sender:)
中。
class ViewController: UIViewController {
...
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let nextVC = segue.destination as? NextViewController {
nextVC.container = container
}
}
}
子类化持久容器
NSPersistentContainer 旨在被子类化。你的子类是一个方便的地方去放置 Core Data 相关的代码像返回数据的子集和调用持久化数据到硬盘的函数。
import CoreData
class PersistentContainer: NSPersistentContainer {
func saveContext(backgroundContext: NSManagedObjectContext? = nil) {
let context = backgroundContext ?? viewContext
guard context.hasChanges else { return }
do {
try context.save()
} catch let error as NSError {
print("Error: \(error), \(error.userInfo)")
}
}
}
以上代码添加一个 saveContext
函数到容器去提高性能通过保存上下文仅仅当有更改发生时。
注意
当把模型层放进自己的框架中时,NSPersistentContainer 的子类定位模型文件在自己的包里。