下面開始學習一下CoreData。
Core Data不是一個關係型資料庫,也不是關係型資料庫管理系統(RDBMS)。
Core Data 為資料變更管理、物件儲存、物件讀取恢復的功能提供了支援。 它可以使用SQLite作為持久化儲存的型別。 它本身並不是一個資料庫(這點很重要,比如,你可以使用Core Data來記錄資料變更,管理資料,但並不能用它向檔案記憶體儲資料)。
一、Core Data基礎
1. Core Data基本架構
在大部分程式中,你要能通過某種方式開啟一個包含物件歸檔的檔案, 這個檔案內至少要有一個根物件的引用。另外,還得能將所有的物件歸檔到檔案中,如果你想要實現撤銷的功能,就還要記錄物件的更改情況。例如,在 Employee的示例程式中,你要能開啟一個包含有employee和department物件歸檔的檔案,相應的,你還有可能將程式中的employee、department物件歸檔到檔案中去。
Figure 1 按照Core Data文件結構管理的物件示意圖
使用Core Data的框架,大多數的功能都可以自動實現,因為我們有managed object context(管理物件的上下文,有時直接叫"Context")。managed object context就像是一個關卡,通過它可以訪問框架底層的物件——這些物件的集合我們稱之為"persistence stack"(資料持久棧)。 managed object context作為程式中物件和外部的資料儲存的中轉站。棧的底部是persistence object stores(持久化資料儲存),請看Figure 2的示意圖。
Figure 2 使用Core Data的文件管理示意圖
2、被管理物件(Managed Object)和上下文(Managed Objects and Contexts)
你可以把被管理物件上下文想象成一個”聰明“的便箋簿。當你從資料持久層獲取物件時,就把這些臨時的資料拷貝拿到寫在自己的便箋簿上(當然,在便箋上物件會 “恢復”以前的物件圖結構)。然後你就可以隨心所欲的修改這些值了(本子是你的,隨便畫都可以),除非你儲存這些資料變化,否則持久層的東西是不會變 的。(跟修改檔案後要儲存是一個道理)。
附在Core Data框架中模型物件(Model objects)常被稱為“被管理物件”(Managed objects)。所有的被管理物件都要通過上下文進行註冊。使用上下文,你可以在物件圖中新增、刪除物件,並記錄物件的更改(包括單個物件,或是物件間 的關係)。記錄更改後就能支援撤銷和重做的功能。同時,上下文還能保證關係更改後物件圖的完整性。
如果你想要儲存所做的修改, 上下文會保證物件的有效性。在驗證有效性後,更改會被寫入到persistent store(持久化儲存層)中。你在程式中的新增和刪除動作都會被作用在儲存的資料中。
在你的一個程式中,可能存在多個上下文。 對於資料儲存(store)中的每個物件,對應的都有唯一的一個被管理物件(managed object)和上下文相關聯(詳情請檢視"Faulting and Uniquing"文件)。換個角度來想,在persistent store中儲存的物件有可能被用在不同的上下文中,每個上下文都有與之對應的被管理物件,被管理物件可以被獨立的修改,這樣就可能在儲存 時導致資料的不一致。Core Data提供了許多解決這個問題的途徑(請檢視"Using Managed Object"一章)。
3、獲取資料的請求(Fetch Requests)
要使用上下文來獲取資料,你需要建立相應的請求(Fetch request)。 Fetch request物件包含你想獲取的物件的描述。例如:“所有 Employee”,或“所有的Employee,department是marketing,按薪資降序排列”。Fetch Request包含三個部分。使用最簡單的寫法,必須指定實體(Entity)的名稱,這就暗示了,每次智慧獲得一種型別的實體。 Fetch Request 還可以包含謂詞(predicate)——注:有些地方也把這個叫斷言,個人感覺謂詞更準確些。謂詞將描述物件需要滿足的條件(這就和我們在SQL里加的 限定條件差不多,正如前面的"All Employees, in the Marketing department")。另外,Fetch Request還可包含一個用於描述排序方式的物件(熟悉的Order by操作)。如圖Figure3所示:
在程式中,你將Fetch Request這個請求傳送給上下文,上下文就會從相關的資料來源中查詢複合條件的物件(也可能找不到),並返回。 所有的被管理物件(managed object)都必須在上下文中註冊,因此通過fetch request獲得的物件自動被註冊。但如前所述,每個在持久儲存層(persistence store)中的物件都對應一個和上下文相關的被管理物件(managed object),因此,如果在上下文中已經存在了fetch request要取的物件,那麼這個被管理物件將被返回。
4、持久化儲存助理(Persistent Store Coordinator)
之前提到過,程式中的物件和外部儲存的資料通過Core Data框架中的一系列物件進行協調,這一系列的物件總的被稱為持久儲存棧(Persistence stack)。在棧頂是被管理物件上下文(Managed object context),而棧底是持久化物件儲存層(Persistence object store)。在它們之間就是持久化儲存助理。如下圖:
事實上,持久化儲存助理定義了一個棧。從設計方面考慮,它就是可以作為上下文的”外觀“。持久化儲存助理智慧關聯一個被管理物件的模型。如果你像要把不同的實體放到不同的儲存中去,就需要為你 的模型實體做“分割槽”,方式是通過定義被管理物件模型的configurations。(請參考"Configurations"一章)。
Figure 4演示了這樣的一個結構:employees和departments儲存在一個檔案中,customers和companies儲存在另外一個檔案中。當你要獲取物件的時候,它們從相關的檔案中自動獲取;當儲存時,又被歸檔到相應的檔案中。
5、持久化儲存(Persistent Stores)
持久化儲存是和單獨的一個檔案或外部的資料關聯的,它負責將資料和上下文中的物件進行對應。通常,需要你直接和持久化物件儲存打交道的地方,就是指定新的、 和程式進行關聯的外部資料的位置(例如,當使用者開啟或儲存一個文件)。大多數需要訪問持久化儲存的動作都由上下文來完成。
程式的程式碼—— 特別是和被管理物件相關的部分——不應該對持久化儲存做任何假設(也就是不需要自己考慮儲存的方式或過程)。 Core Data對幾種檔案格式有原生的支援。你可以選擇一種自己程式需要的。假設在某個階段你決定換一種檔案的格式,而又不想修改程式的框架,而且,你的程式做了適當的抽象(注:這個就屬於設計方面的東東了),這時,你就能嚐到使用Core Data的甜頭了。例如,在最初的設計中,程式只從本地檔案中獲取資料,而你的程式沒有去硬指定對應資料的獲取位置,而是可以在後期指定從遠端位置新增新的資料型別,這樣你就可以使用新的型別,而不需要修改程式碼。(這段還是感覺翻的不太合適)。
6、 被管理物件和被管理物件模型(Managed Objects and the Managed Object Model)
為了管理物件圖,也為了提供物件持久化的功能,Core Data需要對物件有很強的描述能力。被管理物件模型就是程式中物件、實體描述的概要圖,如圖Figure 5所示。建立模型的常用做法是通過Xcode的圖形化建模工具Date Model Design tool。但是如果你願意的話,也可以在執行時通過程式碼來建模。
Figure 5 有兩個實體的物件模型
模型由多個實體描述物件Entity Description構成,每個描述提供實體的某項後設資料,它們包含實體名、實體在程式中的類名(當然,類名和實體名不需要一致)、屬性還有關係。屬性和關係依次被屬性和關係描述物件所代表,如圖Figure 6所示。
Figure 6 帶有兩個屬性和一個關係的的實體描述
被管理物件必須是NSManagedObject或其子類的例項。 NSManagedObject可用來表示任何實體。它使用內部私有的儲存機制來維護自身的屬性,並執行一個被管理物件所必須的基本操作。一個被管理物件擁有一份實體描述的引用。在使用時,它通過實體描述來找到自身的後設資料,包括實體名和屬性、關係的資訊。你也可以繼承NSManagedObject來執 行額外的操作。
被管理物件模型(Managed Object Models)
多數Core Data的功能依賴於你建立的,用來描述程式的實體及其屬性、關係的模型圖。 模型圖由NSManagedObjectModel所表示。一般說來,模型的資訊越充實,Core Data能提供的功能就越好。
被管理物件模型的特性
被管理物件模型是 NSManagedObjectModel的例項。它描述了你在程式中使用的實體的概要資訊。
7、實體(Entities)
Entity代表物件-關係對映的架構,由此可以生成一個物件類,並對應持久儲存中的一個資料表(ORM關係即可建立)。通常是在Xcode 視覺化環境下建立 Entity,也可用程式碼建立(NSEntityDescription 物件)
實體由屬性(property)組成,屬性分成3種型別,特性(attribute)、關係和提取屬性。
Managed Object 表示在執行時建立的該實體的具體例項。
實體和Managed Object間的關係等同於資料庫中資料表與資料記錄之間的關係。
以上內容參考自 http://www.cocoachina.com/iphonedev/sdk/2010/1126/2397.html 並做有修改。