2

Core Data 基础

 3 years ago
source link: http://blog.danthought.com/programming/2016/04/20/core-data-basic/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

从这篇文章,你将学习到有关 Core Data 的基础知识,如何创建 Core Data Stack,了解其中每一个构成部分,示例代码地址,让我们开始吧。

Core Data Basic

Core Data Stack 简介

创建了 Core Data Stack,才能正常地使用 Core Data 存取数据,之所以称呼为 Stack,就如同下图所示上一层依赖于下一层。

Core Data Stack

NSManagedObjectModel

NSManagedObjectModel 描述了存储数据的结构,如果你有关系型数据库的使用经验,你应该明白这就是 Database Schema,和其它所有关系型数据库一样,结构就是实体和关系,如下图所示:

Core Data Data Model Graph

通过 Xcode 创建 Data Model 文件:

Core Data Data Model Create

Data Model 文件以 .xcdatamodeld 做为文件名后缀,Xcode 会将 .xcdatamodeld 文件编译成 .momd,后面会用到这个编译后的文件名:

Core Data Data Model Filename

在 Data Model 文件中设计存储数据的结构,创建实体,定义实体中的属性名和属性类型,还有实体之间的关系。

Core Data Data Model Table 1
Core Data Data Model Table 2

NSPersistentStore

代表数据存储之地,iOS 支持的格式有二进制等,OS X 还支持 XML 格式,这里只说 SQLite 格式。

NSPersistentStoreCoordinator

负责存储,加载和缓存数据,一旦初始化过后,很少需要再和它打交道,初始化的时候需要 NSManagedObjectModel,这样才知道存储数据的结构嘛,还需要 NSPersistentStore,这样才知道以什么样的格式存储在哪里。

NSManagedObjectContext

这是你主要打交道的类,通过此类来查询,新增,修改和删除数据,所有你操作过的数据对象,都会在这里暂存,也是为了提高频繁访问的效率,值得注意一点是此类不是线程安全的,简单来说,如果你是在主线程创建的此类的对象,那么只能在主线程通过此对象操作数据,否则就会出问题。

代码创建 Core Data Stack

import Foundation
import CoreData

class PersistenceController {
  
  static let sharedInstance = PersistenceController()
  
  fileprivate let model = "Model"
  fileprivate let db = "db.sqlite"
  fileprivate var moc: NSManagedObjectContext
  
  fileprivate init() {
    // 找到通过 Xcode 创建的 Data Model 文件
    let modelURL = Bundle.main.url(forResource: model, withExtension: "momd")
    // 创建 NSManagedObjectModel
    let mom = NSManagedObjectModel(contentsOf: modelURL!)
    // 创建 NSPersistentStoreCoordinator
    let psc = NSPersistentStoreCoordinator(managedObjectModel: mom!)
    
    // 创建 NSManagedObjectContext,并指定是主线程类型
    moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
    
    // NSManagedObjectContext 关联 NSPersistentStoreCoordinator
    moc.persistentStoreCoordinator = psc
    
    let fileManager = FileManager.default
    
    // 设置 NSPersistentStore 需要的一些参数
    var options = [String: Any]()
    options[NSMigratePersistentStoresAutomaticallyOption] = true
    options[NSInferMappingModelAutomaticallyOption] = true
    
    // 指定 SQLite 数据库文件存储位置
    let localStoreURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).last!.appendingPathComponent(db)
    
    do {
      try psc.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: localStoreURL, options: options)
    } catch {
      print("!!! Error: adding local persistent store to coordinator !!!\n\(error)\n")
    }
  }
  
}

NSManagedObject

每一个 NSManagedObject 对象代表数据库表中每一行数据,封装了你定义的数据类型和关系。

访问属性,会触发 KVO 通知:

let object = NSEntityDescription.insertNewObject(forEntityName: "Category", into: moc)
object.setValue("Running", forKey: "name")
object.value(forKey: "name")

原始访问属性,不会触发 KVO 通知:

let object = NSEntityDescription.insertNewObject(forEntityName: "Category", into: moc)
object.setPrimitiveValue("Running", forKey: "name")
object.primitiveValue(forKey: "name")

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK