Core Data

Core Data是蘋果公司所開發的macOS作業系統（舊稱：Mac OS X及OS X）中Cocoa API的一部分，首次在Mac OS X 10.4 Tiger與iOS 3.0系統中出現。它允許按照實體-屬性-值模型組織數據，並以XML，二進位文件或SQLite數據文件的格式將其序列化。Core Data允許用戶使用代表實體和實體間關係的高層對象來操作數據。它也可以管理序列化的數據，提供對象生存期管理與object graph管理，包括存儲。Core Data直接與SQLite交互，避免開發者使用原本的SQL語句。

就像Cocoa綁定在模型-視圖-控制器設計中做了很多控制器的工作一樣，Core Data做了很多數據模型的工作。它的主要任務是負責數據更改的管理，序列化到磁碟，最小化記憶體占用，以及查詢數據。

專長於Core Data及Cocoa軟體開發的資訊圖書作家Marcus Zarra曾說：

簡單的說，Core Data就是可以存儲到磁碟的對象圖，...Core Data可以幫我們做很多工作。它可以作為軟體的整個模型層。它不僅僅在磁碟上存儲數據，也把我們需要的數據對象讀取到記憶體中。

## 使用方法

Core Data使用包括實體和實體間關係，以及查找符合某些條件的實體的請求等內容的高層數據模型描述數據。開發者可以在純對象層上查找與管理這些數據，而不必擔心存儲和查找的實現細節。Interface Builder中的控制器對象可以直接獲取與管理實體，若與Cocoa綁定結合，則可以在不寫自定義代碼的情況下讓使用者界面顯示、修改與管理數據模型中的大部分內容。

例如：開發者希望開發一個管理vCard的程序。作者希望使用Core Data將一些vCard讀入對象中，然後把它們存入一個大XML文件中。開發者需要在Xcode中建立數據模型，然後到Interface Builder中加入Core Data Entity項以創建其數據模型對應的GUI。然後，開發者可以加入標準的Objective-C代碼以讀取vCard，並將數據寫入由Core Data管理的實體中。在此，開發者的代碼是管理Core Data對象，而非其對應的vCard。最後，將`Save`菜單項連接到控制器對象對應的方法上，使得控制器在接到存儲消息後自動的檢查數據堆棧，確認數據是否合法，最後利用當前更改重寫對應的Core Data文檔。在整個過程中，開發者只需要專注於將vCard文件轉換為Core Data實體的過程，而不需關心例如數據的顯示、合法性檢查、存儲等其它部分，提高了開發效率。

Core Data is organized into a large hierarchy of classes, though interaction is only prevalent with a small set of them.

Core Data由相對龐大的類繼承體系組成，但開發者需要關注的接口只是其中的一個相對小的子集。

類名｜用途｜關鍵方法

NSManagedObject｜、數據對象、管理屬性｜、-entity、-valueForKey:、-setValue: forKey:

NSManagedObjectContext｜、資料庫、獲取與存儲｜、-executeFetchRequest: error:、-save

NSManagedObjectModel｜、數據模型｜、-entities、-fetchRequestTemplateForName:、-setFetchRequestTemplate: forName:

NSFetchRequest｜、請求數據｜、-setEntity:、-setPredicate:、-setFetchBatchSize:

NSPersistentStoreCoordinator｜、中介、存儲數據｜、-addPersistentStoreWithType: configuration: URL: options: error:、-persistentStoreForURL:

NSPredicate｜、確定查詢條件｜、+predicateWithFormat:、-evaluateWithObject:

## 存儲格式

Core Data可以將數據存儲為XML，二進位文件或SQLite文件。在Mac OS X 10.5 Leopard及以後的版本中，開發者也可以通過繼承NSPersistentStore類以創建自定義的存儲格式。每種方法都有其優缺點，例如XML的可讀性，SQLite的節約空間等。Core Data的這一方面類似於原始的Enterprise Objects Framework（EOF）系統，但EOF中開發者可以使用相對簡潔的查詢方式，而在Core Data中，只能使用一個語法類似SQL子集的查詢語言，稱為Predicate。

Core Data是標準化的，可以自由的讀寫Xcode數據模型文件（通常是.xcdatamodel文件）。與EOF不同，Core Data目前沒有設計多用戶或多線程訪問模式。模型遷移通常也需要代碼，若其它開發者依賴於某個數據模型，則該數據模型的設計者可能在模型發生改變時需要與新數據模型一起提供版本轉換代碼。

## 歷史與發展

Core Data的很大一部分設計都歸功於早期的NeXT產品，Enterprise Objects Framework（EOF）。

## 參考文獻

- 蘋果公司 (2009年9月17日). "Core Data Programming Guide". Retrieved from http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html
- 蘋果公司 (2009年9月). "Core Data Tutorial for iPhone OS". Retrieved from https://web.archive.org/web/20100323200755/http://developer.apple.com/iPhone/library/documentation/DataManagement/Conceptual/iPhoneCoreData01/Introduction/Introduction.html
- 蘋果公司 (2010年6月14日). Predicate Programming Guide. 來自
- 蘋果公司 (2006年). "EOModeler User Guide". Retrieved from http://developer.apple.com/legacy/mac/library/documentation/WebObjects/UsingEOModeler/Introduction/Introduction.html#//apple_ref/doc/uid/TP30001018-CH201-TP1
- Jurewitz, M. & Apple Inc. (2010). "iPhone Development Videos: Working With Core Data". Retrieved from http://developer.apple.com/videos/iphone/#video-advanced-coredata
- Stevenson, S. (2005). "Core Data Class Overview". Retrieved from http://cocoadevcentral.com/articles/000086.php
- Zarra, M. S. (2009). Core Data Apple's API for Persisting Data on Mac OS X. The Pragmatic Programmers.
- LaMarche, J., & Mark, D. (2009). More iPhone 3 Development: Tackling iPhone SDK 3. Apress.

## 外部連結

- Apple Inc. (2006). "Developing With Core Data". Retrieved from http://developer.apple.com/macosx/coredata.html
- Apple Inc. (2009). "Web Objects Tutorial". Retrieved from http://developer.apple.com/legacy/mac/library/documentation/DeveloperTools/Conceptual/WOTutorial/Introduction/Introduction.html
- CocoaDev. (n.d.). Retrieved from https://web.archive.org/web/20080801025517/http://www.cocoadev.com/
- Stevenson, S. (2005). "Build A Core Data Application". Retrieved from http://cocoadevcentral.com/articles/000085.php

## 基本資料

- 開發者：蘋果公司
- 作業系統：macOS、iOS
- 許可協議：專有
- 網站： Apple Developer Documentation