本章節提供關於「被管理對象(Managed Object)」的基礎說明,如如何存儲被管理對象的數據、如何實現一個自定義被管理對象類、對象的生命週期和斷層(Faulting)等。html
被管理對象是NSManagedObject
類的實例或者NSManagedObject
子類的實例,其表現爲一個數據實體的實例。NSManagedObject
用於實現全部被管理數據模型所須要的基礎行爲的通用類。咱們能夠自定義建立NSManagedObject
的子類。若是咱們不須要給實體添加額外的操做邏輯,咱們就不須要給爲實體單獨定製 在使用Swift語言的過程當中,爲每一個實體建立一個子類,而後進行相應的擴展,是有必要的。iosNSManagedObject
的子類。
一個被管理對象與一個實體描述類(NSEntityDescription
的實例)相關聯,這個實體描述類提供有關這個實體的元數據的描述(實體名稱、實體屬性、實體間的關係等)。還與一個被管理對象上下文相關聯,這個上下文追蹤這個被管理對象的改變路徑。數據庫
在被管理上下文中,一個被管理對象表示持久化存儲當中一條記錄。在一個給定的上下文,對於一條給定的持久化存儲記錄,只能有一個相對應的被管理對象,可是也許有多個上下文包含有表現通一個記錄的不一樣的被管理對象。swift
在某些方面,一個NSManagedObject
泛型容器對象,有效地爲NSEntityDescription
對象定義的屬性提供存儲字典。NSManagedObject
提供多種屬性值,常見類型包括字符串,日期,和數量(詳情請參閱NSAttributeDescription
)。所以一般不須要在子類中定義實例變量。若是你使用二進制大數據對象有一些性能方面的考慮要牢記(Large Data Objects(BLOBs))。數組
默認狀況下,NSManagedObject
將它的屬性做爲對象存儲在一個內部結構中,一般,CoreData使用在它自己控制下的存儲要比使用自定義實例變量更高效。app
有時您須要使用不被直接支持的類型,例如顏色和結構。例如,在一個圖形應用程序,你可能想定義一個矩形實體,具備顏色屬性和範圍,分別是NSColor
實例和NSRect
結構。這種狀況須要您建立一個NSManagedObject
的子類。框架
NSManagedObject
使用NSDate
對象表明日期屬性,使用基於GMT的NSTimeInterval
值存儲時間。時區沒有明確地被存儲-事實上你應該一直使CoreData日期屬性基於GMT,以便規範地搜索數據庫。若是你須要保存時區信息,你須要存儲一個時區屬性在你的模型中,這可能須要您建立一個NSManagedObject
的子類。性能
當你已經定義了你的被管理對象模型,而且初始化好CoreData棧以後,你已經作好準備爲持久化建立對象了。學習
NSManagedObject
實例須要兩個元素,一個是實體對象描述(NSEntityDescription
),一個是持久化上下文(NSManagedObjectContext
)。咱們能夠利用實體對象描述來建立一個新的被管理對象。以下所示:fetch
var user = NSEntityDescription.insertNewObjectForEntityForName("User", inManagedObjectContext: context!) as! User
注意:
- 上面實例所使用的
User
爲已經建立好的NSManagedOobject
類的子類。
由於全部對被管理對象的改變,都須要使用其所在的上下文進行持久化操做,因此保存被管理對象實例,實際上就是調用持久話上下文對象的持久化操做。以下所示。
func saveContext () { if let moc = self.managedObjectContext { var error: NSError? = nil if moc.hasChanges && !moc.save(&error) { NSLog("Unresolved error \(error), \(error!.userInfo)") abort() } } }
上面的代碼判斷在上下文中的被管理對象是否有所變化(經過判斷.hasChanges
),若是有變化,則調用.save()
方法,來執行持久話操做。
數據被存儲在CoreData持久話存儲當中,可使用一個NSFetchRequest
來訪問已經存在的數據。從CoreData中提取數據是這個框架最有力的特性。
咱們可使用以下步驟來提取持久化上下文當中的被管理對象數據:
NSFetchRequest
)具體實現以下所示:
// 1. var moc = UIApplication.sharedApplication().delegate?.managedObjectContext // 2. var request = NSFetchRequest(entityName: "User") // 3. & 4. var results = moc?.executeFetchRequest(request, error: nil) as! [User] // if results != nil { NSLog("Error fetching Employee objects: \(error), \(error!.userInfo)") // 提取空值&提取出錯處理 } // 5. // ... 結果操做省略
.executeFetchRequest
有兩種可能的執行結果,一種是返回一個數組對象(存儲提取結果),一種是返回nil
。若是返回nil
,就說明本次提取從CoreData取得了一個異常,此時就須要對此異常進行處理,以免Bug擴大化。
在實際生產環境中,提取結果每每是很複雜的,爲了實現對複雜結果的提取,咱們可使用NSPredicate
來做爲數據提取請求的一個__過濾條件__。好比咱們要從持久化上下文中提取出全部name
值爲Aaron
的數據對象,可使用以下的謂詞(NSPredicate
)。
var predicate = NSPredicate(format: "%K like %@", argumentArray: ["name", "Aaron"])
注意:
- 有關詳細的謂詞格式、字符,請點擊查看。
在定製好用於過濾提取結果的謂詞後,咱們須要將這個謂詞賦予提取請求。
request.predicate = predicate
以後,咱們就能夠像上一節中所提到的方式進行數據的提取了。
對於提取結果的過濾,除了使用謂詞外,咱們還能夠對提取請求自己進行定製,以實現:
關於更多的關於提取請求自己的配置,能夠點擊這裏查看。