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 很好的支持,以及數據遷移備份,這些均可以很容易實現。筆者認爲,徹底能夠考慮使用它作客戶端的數據持久化方案。