Core Data 是 iOS3.0 时引入的一个数据持久化的框架。与 sqlite 对比最大的优势莫过于支持对象的存储,苹果的官方文档说其简化了数据库的操做,使用 Core Data 确实能够大量减小代码中的 SQL 语句。sql
但是现状,你们对于持久化的选择方案仍多数是 FMDB。笔者猜想,最大的缘由可能就是性能。数据库
Core Data 是一个模型层的技术,帮助开发者创建表明程序状态的模型层。同时也是一种持久化技术,它能将模型对象的状态持久化到磁盘。它是彻底独立于 UI 层级的框架,是做为模型层框架被设计出来的。swift
Core Data 不是一个 O/RM,但它比 O/RM 能作的更多。它也不是一个 SQL wrapper。它默认使用 SQL,但它是一种更高级的抽象概念。缓存
Core Data 有至关多可用的组件。当全部的组件都捆绑到一块儿的时候,咱们把它称做 Core Data 堆栈,这个堆栈有两个主要部分。多线程
一部分是关于对象图管理,这正是你须要很好掌握的那一部分,而且知道怎么使用。 另外一部分是关于持久化,好比,保存你模型对象的状态,而后再恢复模型对象的状态。app
堆栈结构以下框架
NSPersistentStoreCoordinator 是一个位于本地存储文件与缓存层(NSManagedObjectContext)之间的一个持久化层,它是真实操做数据库本地文件。ide
NSManagedObjectContext 是一个被管理数据的上下文,它其实是对全部数据库操做的一个缓存层,把全部的操做都先缓存起来避免大量磁盘 IO 形成不流畅,在操做完数据库后调用其 save 方法,就能够把数据库操做提交给持久化层(NSPersistentStoreCoordinator),由持久化层一次性写入数据库文件。性能
NSManagedObject 是被管理的数据记录,对应数据库的一个表。学习
另外,Core Data 能够将多个 stores 附属于同一个持久化存储协调器,而且除了存储 SQL 格式外,还有不少存储类型可供选择。 最多见的方案以下
下面是笔者定义的一个 Event 表的元素组成
定义数据模型
class MXWEventModel: NSObject {
var id: Int64
var time: Date
var title: String
var detail: String
var addr: String
init(id: Int64, title: String, detail: String, addr: String, time: Date){}
}
复制代码
let context = persistentContainer.viewContext
public func add(model: AnyObject) {
let eventModel: MXWEventModel = model as! MXWEventModel
let entity = NSEntityDescription.entity(forEntityName: @"MXWEvent", in: context!)
let obj = NSManagedObject(entity: entity!, insertInto: context)
obj.setValue(eventModel.id, forKey: "id")
obj.setValue(eventModel.title, forKey: "title")
obj.setValue(eventModel.detail, forKey: "detail")
obj.setValue(eventModel.time, forKey: "time")
obj.setValue(eventModel.addr, forKey: "addr")
do {
try context?.save()
} catch {
print(error)
}
}
复制代码
public func delete(id: Int64) {
let request = NSFetchRequest<NSFetchRequestResult>(entityName: @"MXWEvent")
request.predicate = NSPredicate(format: "id==\(id)")
let deleteRequest = NSBatchDeleteRequest(fetchRequest: request)
do {
try context?.execute(deleteRequest)
} catch {
print(error)
}
}
复制代码
public func update(id: Int64, model: AnyObject) {
let eventModel: MXWEventModel = model as! MXWEventModel
let request = NSFetchRequest<NSFetchRequestResult>(entityName: @"MXWEvent")
request.predicate = NSPredicate(format: "id==\(id)")
do {
let eventObj = try context?.fetch(request)
let updateObj = eventObj?.first as! NSManagedObject
updateObj.setValue(eventModel.title, forKey: "title")
updateObj.setValue(eventModel.detail, forKey: "detail")
updateObj.setValue(eventModel.time, forKey: "time")
updateObj.setValue(eventModel.addr, forKey: "addr")
do {
try context?.save()
} catch {
print(error)
}
} catch {
print(error)
}
}
复制代码
public func fetch(id: Int64) -> AnyObject? {
let request = NSFetchRequest<NSFetchRequestResult>(entityName: @"MXWEvent")
request.predicate = NSPredicate(format: "id==\(id)")
do {
let r = try context?.fetch(request)
for data in r as! [NSManagedObject] {
let m = MXWEventModel(id: data.value(forKey: "id") as! Int64, title: data.value(forKey: "title") as! String, detail: data.value(forKey: "detail") as! String, addr: data.value(forKey: "addr") as! String, time: data.value(forKey: "time") as! Date)
return m
}
} catch {
print(error)
}
}
复制代码
在功能迭代过程当中,不免会遇到要修改 .xcdatamodeld
文件。例如,新增或删除一个实体、增长或删除一个原有实体的属性等。若是开发者没有设置数据迁移,那更新后原有的数据将会被清空,因此此时须要进行数据的迁移操做。
Core Data 能够设置轻量级的数据迁移,系统会自动分析差别,进行映射,这种方式只适用于简单的增删实体或是增删属性等操做。除此以外还有一种至关复杂的自定义数据迁移。
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "Demo")
container.loadPersistentStores(completionHandler: { storeDescription, error in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
// 设置数据迁移(shouldMigrateStoreAutomatically 默认值为 true)
if let sDescription: NSPersistentStoreDescription = storeDescription as NSPersistentStoreDescription {
sDescription.shouldMigrateStoreAutomatically = true
sDescription.shouldInferMappingModelAutomatically = false
}
})
return container
}()
复制代码
对于 Core Data,Apple 官方好久以前就已经推出,可是并不受开发者青睐。笔者在这段时间的学习过程当中也在思考这个问题。
下面是笔者学习中遇到的注意点:
最后,文章开头给出了性能比较。可是,笔者认为,在客户端并无很大量的数据写入,只要开发者在使用过程当中稍做注意,性能应该不是否决 Core Data 技术方案的理由。反倒,Core Data 对 iCloud 很好的支持,以及数据迁移备份,这些均可以很容易实现。笔者认为,彻底能够考虑使用它作客户端的数据持久化方案。