深刻淺出 Cocoa 之 Core Data(1)- 框架詳解
CC 許可,轉載請註明出處
Core data 是 Cocoa 中處理數據,綁定數據的關鍵特性,其重要性不言而喻,但也比較複雜。Core Data 相關的類比較多,初學者每每不太容易弄懂。計劃用三個教程來說解這一部分:
框架詳解:講解 Core data 框架,運做過程,設計的類;
Core data應用程序示例:經過生成一個使用 Core data 的應用程序來說解如何 在 XCode 4 中使用 Core data。
手動建立Core data示例:不利用框架自動生成代碼,徹底本身編寫全部的 Core data 相關代碼的命令行應用程序來深刻講解 Core data的使用。
本文爲第一部份:框架詳解
一,概觀
下面先給出一張類關係圖,讓咱們對它有個整體的認識。
在上圖中,咱們能夠看到有五個相關模塊:
1, Managed Object Model
Managed Object Model 是描述應用程序的數據模型,這個模型包含實體(Entity),特性(Property),讀取請求(Fetch Request)等。(下文都使用英文術語。)
2,Managed Object Context
Managed Object Context 參與對數據對象進行各類操做的全過程,並監測數據對象的變化,以提供對 undo/redo 的支持及更新綁定到數據的 UI。
3,Persistent Store Coordinator
Persistent Store Coordinator 至關於數據文件管理器,處理底層的對數據文件的讀取與寫入。通常咱們無需與它打交道。
4,Managed Object
Managed Object 數據對象,與 Managed Object Context 相關聯。
5,Controller
圖中綠色的 Array Controller, Object Controller, Tree Controller 這些控制器,通常都是經過 control+drag 將 Managed Object Context 綁定到它們,這樣咱們就能夠在 nib 中可視化地操做數據。
這寫模塊是怎樣運做的呢?
1,應用程序先建立或讀取模型文件(後綴爲xcdatamodeld)生成 NSManagedObjectModel 對象。Document應用程序是通常是經過 NSDocument 或其子類 NSPersistentDocument)從模型文件(後綴爲 xcdatamodeld)讀取。
2,而後生成 NSManagedObjectContext 和 NSPersistentStoreCoordinator 對象,前者對用戶透明地調用後者對數據文件進行讀寫。
3,NSPersistentStoreCoordinator 負責從數據文件(xml, sqlite,二進制文件等)中讀取數據生成 Managed Object,或保存 Managed Object 寫入數據文件。
4,NSManagedObjectContext 參與對數據進行各類操做的整個過程,它持有 Managed Object。咱們經過它來監測 Managed Object。監測數據對象有兩個做用:支持 undo/redo 以及數據綁定。這個類是最常被用到的。
5,Array Controller, Object Controller, Tree Controller 這些控制器通常與 NSManagedObjectContext 關聯,所以咱們能夠經過它們在 nib 中可視化地操做數據對象。
二, Model class
模型有點像數據庫的表結構,裏面包含 Entry, 實體又包含三種 Property:Attribute(屬性),RelationShip(關係), Fetched Property(讀取屬性)。Model class 的名字多以 "Description" 結尾。咱們能夠看出:模型就是描述數據類型以及其關係的。
主要的 Model class 有:
Model Classes
Managed Object Model |
NSManagedObjectModel |
數據模型 |
Entity |
NSEntityDescription |
抽象數據類型,至關於數據庫中的表 |
Property |
NSPropertyDescription |
Entity 特性,至關於數據庫表中的一列 |
> Attribute |
NSAttributeDescription |
基本數值型屬性(如Int16, BOOL, Date等類型的屬性) |
> Relationship |
NSRelationshipDescription |
屬性之間的關係 |
> Fetched Property |
NSFetchedPropertyDescription |
查詢屬性(至關於數據庫中的查詢語句) |
1)Entity - NSEntityDescription
Entity 至關於數據庫中的一個表,它描述一種抽象數據類型,其對應的類爲 NSManagedObject 或其子類。
NSEntityDescription 經常使用方法:
+insertNewObjectForEntityForName:inManagedObjectContext: 工廠方法,根據給定的 Entity 描述,生成相應的 NSManagedObject 對象,並插入 ManagedObjectContext 中。
-managedObjectClassName
返回映射到 Entity 的 NSManagedObject 類名
-attributesByName
以名字爲 key, 返回 Entity 中對應的 Attributes
-relationshipsByName
以名字爲 key, 返回 Entity 中對應的 Relationships
2)Property - NSPropertyDescription
Property 爲 Entity 的特性,它至關於數據庫表中的一列,或者 XML 文件中的 value-key 對中的 key。它能夠描述實體數據(Attribute),Entity之間的關係(RelationShip),或查詢屬性(Fetched Property)。
> Attribute - NSAttributeDescription
Attribute 存儲基本數據,如 NSString, NSNumber or NSDate 等。它能夠有默認值,也可使用正則表達式或其餘條件對其值進行限定。一個屬性能夠是 optional 的。
> Relationship - NSRelationshipDescription
Relationship 描述 Entity,Property 之間的關係,能夠是一對一,也能夠是一對多的關係。
> Fetched Property - NSFetchedPropertyDescription
Fetched Property 根據查詢謂詞返回指定 Entity 的符合條件的數據對象。
上面說的比較抽象,舉個例子來講,見圖:
咱們有一個 CocoaDataDemo.xcdatamodeld 模型文件,應用程序根據它生成一個 NSManagedObjectModel 對象,這個模型有三個 Entity,每一個 Entity 又可包含 Attribute Relationship, Feteched Property 三種類型的 Property。在本例中, Author Entity 包含兩個Attribute : name 和 email,它們對於的運行時類均爲 NSManagedObject;還包含一個與 Post 的 Relationship;沒有設置 Feteched Property。
咱們一般使用 KVC 機制來訪問 Property。下面來看代碼:
- NSManagedObjectContext * context = [[NSApp delegate] managedObjectContext];
- NSManagedObject * author = nil;
-
- author = [NSEntityDescription insertNewObjectForEntityForName: @"Author" inManagedObjectContext: context];
- [author setValue: @"nemo@pixar.com" forKey: @"email"];
-
- NSLog (@"The Author's email is: %@", [author valueForKey:@"email"]);
在上面代碼中,咱們先取得 NSManagedObjectContext, 而後調用 NSEntityDescription 的方法,以 Author 爲實體模型,生成對應的 NSManagedObject 對象,插入 NSManagedObjectContext 中,而後給這個對象設置特性 email 的值。
三,運行時類與對象
> Managed Object - NSManagedObject
Managed Object 表示數據文件中的一條記錄,每個 Managed Object 在內存中對應 Entity 的一個數據表示。Managed Object 的成員爲 Entity 的 Property 所描述。
好比在上面的代碼,author 這個 NSManagedObject,對應名爲 Author 的 Entity。
每個 Managed Object 都有一個全局 ID(類型爲:NSManagedObjectID)。Managed Object 會附加到一個 Managed Object Context,咱們能夠經過這個全局 ID 在 Managed Object Context 查詢對應的 Managed Object。
NSManagedObject 經常使用方法
-entity |
獲取其 Entity |
-objectID |
獲取其 Managed Object ID |
-valueForKey: |
獲取指定 Property 的值 |
-setValue: forKey: |
設定指定 Property 的值 |
> Managed Object Context - NSManagedObjectContext
Managed Object Context 的做用至關重要,對數據對象進行的操做都與它有關。當建立一個數據對象並插入 Managed Object Context 中,Managed Object Context 就開始跟蹤這個數據對象的一切變更,並在合適的時候提供對 undo/redo 的支持,或調用 Persistent Store Coordinato 將變化保存到數據文件中去。
一般咱們將 controller 類(如:NSArrayController,NSTreeController)或其子類與 Managed Object Context 綁定,這樣就方便咱們動態地生成,獲取數據對象等。
NSManagedObjectContext 經常使用方法
-save: |
將數據對象保存到數據文件 |
-objectWithID: |
查詢指定 Managed Object ID 的數據對象 |
-deleteObject: |
將一個數據對象標記爲刪除,可是要等到 Context 提交更改時才真正刪除數據對象 |
-undo |
回滾最後一步操做,這是都 undo/redo 的支持 |
-lock |
加鎖,經常使用於多線程以及建立事務。同類接口還有:-unlock and -tryLock |
-rollback |
還原數據文件內容 |
-reset |
清除緩存的 Managed Objects。只應當在添加或刪除 Persistent Stores 時使用 |
-undoManager |
返回當前 Context 所使用的 NSUndoManager |
-assignObject: toPersistantStore: |
因爲 Context 能夠管理從不一樣數據文件而來的數據對象, 這個接口的做用就是指定數據對象的存儲數據文件(經過指定 PersistantStore 實現) |
-executeFetchRequest: error: |
執行 Fetch Request 並返回全部匹配的數據對象 |
> Persistent Store Coordinator - NSPersistentStoreCoordinator
使用 Core Data document 類型的應用程序,一般會從磁盤上的數據文中中讀取或存儲數據,這寫底層的讀寫就由 Persistent Store Coordinator 來處理。通常咱們無需與它直接打交道來讀寫文件,Managed Object Context 在背後已經爲咱們調用 Persistent Store Coordinator 作了這部分工做。
NSPersistentStoreCoordinator 經常使用方法
-addPersistentStoreForURL:configuration:URL:options:error: |
裝載數據存儲,對應的卸載數據存儲的接口爲 -removePersistentStore:error: |
-migratePersistentStore:toURL:options:withType:error: |
遷移數據存儲,效果與 "save as"類似,可是操做成功後, 遷移前的數據存儲不可再使用 |
-managedObjectIDForURIRepresentation: |
返回給定 URL所指示的數據存儲的 object id,若是找不到匹配的數據存儲則返回 nil |
-persistentStoreForURL: |
返回指定路徑的 Persistent Store |
-URLForPersistentStore: |
返回指定 Persistent Store 的存儲路徑 |
> Persistent Document - NSPersistentDocument
NSPersistentDocument 是 NSDocument 的子類。 multi-document Core Data 應用程序使用它來簡化對 Core Data 的操做。一般使用 NSPersistentDocument 的默認實現就足夠了,它從 Info.plist 中讀取 Document types 信息來決定數據的存儲格式(xml,sqlite, binary)。
NSPersistentDocument 經常使用方法
-managedObjectContext |
返回文檔的 Managed Object Context,在多文檔應用程序中,每一個文檔都有本身的 Context。 |
-managedObjectModel |
返回文檔的 Managed Object Model |
四,Fetch Requests
Fetch Requests 至關於一個查詢語句,你必須指定要查詢的 Entity。咱們經過 Fetch Requests 向 Managed Object Context 查詢符合條件的數據對象,以 NSArray 形式返回查詢結果,若是咱們沒有設置任何查詢條件,則返回該 Entity 的全部數據對象。咱們可使用謂詞來設置查詢條件,一般會將經常使用的 Fetch Requests 保存到 dictionary 以重複利用。
示例:
- NSManagedObjectContext * context = [[NSApp delegate] managedObjectContext];
- NSManagedObjectModel * model = [[NSApp delegate] managedObjectModel];
- NSDictionary * entities = [model entitiesByName];
- NSEntityDescription * entity = [entities valueForKey:@"Post"];
-
- NSPredicate * predicate;
- predicate = [NSPredicate predicateWithFormat:@"creationDate > %@", date];
-
- NSSortDescriptor * sort = [[NSortDescriptor alloc] initWithKey:@"title"];
- NSArray * sortDescriptors = [NSArray arrayWithObject: sort];
-
- NSFetchRequest * fetch = [[NSFetchRequest alloc] init];
- [fetch setEntity: entity];
- [fetch setPredicate: predicate];
- [fetch setSortDescriptors: sortDescriptors];
-
- NSArray * results = [context executeFetchRequest:fetch error:nil];
- [sort release];
- [fetch release];
在上面代碼中,咱們查詢在指定日期以後建立的 post,並將查詢結果按照 title 排序返回。
NSFetchRequest 經常使用方法
-setEntity: |
設置你要查詢的數據對象的類型(Entity) |
-setPredicate: |
設置查詢條件 |
-setFetchLimit: |
設置最大查詢對象數目 |
-setSortDescriptors: |
設置查詢結果的排序方法 |
-setAffectedStores: |
設置能夠在哪些數據存儲中查詢 |