Core Data 學習筆記(三)被管理對象

目錄

5、被管理對象

本章節提供關於「被管理對象(Managed Object)」的基礎說明,如如何存儲被管理對象的數據、如何實現一個自定義被管理對象類、對象的生命週期和斷層(Faulting)等。html

5.1 基礎

被管理對象是NSManagedObject類的實例或者NSManagedObject子類的實例,其表現爲一個數據實體的實例。NSManagedObject用於實現全部被管理數據模型所須要的基礎行爲的通用類。咱們能夠自定義建立NSManagedObject的子類。若是咱們不須要給實體添加額外的操做邏輯,咱們就不須要給爲實體單獨定製NSManagedObject的子類。 在使用Swift語言的過程當中,爲每一個實體建立一個子類,而後進行相應的擴展,是有必要的。ios

一個被管理對象與一個實體描述類(NSEntityDescription的實例)相關聯,這個實體描述類提供有關這個實體的元數據的描述(實體名稱、實體屬性、實體間的關係等)。還與一個被管理對象上下文相關聯,這個上下文追蹤這個被管理對象的改變路徑。數據庫

在被管理上下文中,一個被管理對象表示持久化存儲當中一條記錄。在一個給定的上下文,對於一條給定的持久化存儲記錄,只能有一個相對應的被管理對象,可是也許有多個上下文包含有表現通一個記錄的不一樣的被管理對象。swift

5.2 屬性和數據存儲

在某些方面,一個NSManagedObject泛型容器對象,有效地爲NSEntityDescription對象定義的屬性提供存儲字典。NSManagedObject提供多種屬性值,常見類型包括字符串,日期,和數量(詳情請參閱NSAttributeDescription )。所以一般不須要在子類中定義實例變量。若是你使用二進制大數據對象有一些性能方面的考慮要牢記(Large Data Objects(BLOBs))。數組

5.2.1 使用非標準屬性

默認狀況下,NSManagedObject將它的屬性做爲對象存儲在一個內部結構中,一般,CoreData使用在它自己控制下的存儲要比使用自定義實例變量更高效。app

有時您須要使用不被直接支持的類型,例如顏色和結構。例如,在一個圖形應用程序,你可能想定義一個矩形實體,具備顏色屬性和範圍,分別是NSColor實例和NSRect結構。這種狀況須要您建立一個NSManagedObject的子類。框架

5.2.2 日期、時間和存儲時區

NSManagedObject使用NSDate對象表明日期屬性,使用基於GMT的NSTimeInterval值存儲時間。時區沒有明確地被存儲-事實上你應該一直使CoreData日期屬性基於GMT,以便規範地搜索數據庫。若是你須要保存時區信息,你須要存儲一個時區屬性在你的模型中,這可能須要您建立一個NSManagedObject的子類。性能

6、被管理對象的建立與刪除

當你已經定義了你的被管理對象模型,而且初始化好CoreData棧以後,你已經作好準備爲持久化建立對象了。學習

6.1 建立被管理對象

NSManagedObject實例須要兩個元素,一個是實體對象描述(NSEntityDescription),一個是持久化上下文(NSManagedObjectContext)。咱們能夠利用實體對象描述來建立一個新的被管理對象。以下所示:fetch

var user = NSEntityDescription.insertNewObjectForEntityForName("User", inManagedObjectContext: context!) as! User

注意:

  • 上面實例所使用的User爲已經建立好的NSManagedOobject類的子類。

6.2 保存被管理對象實例

由於全部對被管理對象的改變,都須要使用其所在的上下文進行持久化操做,因此保存被管理對象實例,實際上就是調用持久話上下文對象的持久化操做。以下所示。

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()方法,來執行持久話操做。

6.3 提取持久化數據

數據被存儲在CoreData持久話存儲當中,可使用一個NSFetchRequest來訪問已經存在的數據。從CoreData中提取數據是這個框架最有力的特性。

6.3.1 提取被管理對象實例

咱們可使用以下步驟來提取持久化上下文當中的被管理對象數據:

  1. 取得當前運行應用的持久化上下文
  2. 根據提取數據的須要,建立提取請求(NSFetchRequest
  3. 結合提取數據請求,在持久化上下文中執行數據提取操做
  4. 將提取出的數據賦值給一個合適的數組
  5. 使用這個數組

具體實現以下所示:

// 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擴大化。

6.3.2 過濾提取結果

在實際生產環境中,提取結果每每是很複雜的,爲了實現對複雜結果的提取,咱們可使用NSPredicate來做爲數據提取請求的一個__過濾條件__。好比咱們要從持久化上下文中提取出全部name值爲Aaron的數據對象,可使用以下的謂詞(NSPredicate)。

var predicate = NSPredicate(format: "%K like %@", argumentArray: ["name", "Aaron"])

注意:

在定製好用於過濾提取結果的謂詞後,咱們須要將這個謂詞賦予提取請求。

request.predicate = predicate

以後,咱們就能夠像上一節中所提到的方式進行數據的提取了。

對於提取結果的過濾,除了使用謂詞外,咱們還能夠對提取請求自己進行定製,以實現:

  • 提取結果數量限制
  • 提取結果偏移量
  • 提取結果的排序
  • 提取結果的類型(默認爲數組)

關於更多的關於提取請求自己的配置,能夠點擊這裏查看

參考

相關文章
相關標籤/搜索