1.1 創(chuàng)建一個(gè)Managed Object Model (Core Data Programming Guide翻譯)

這是蘋果官方文檔 Core Data Programming Guide 的渣翻譯。

Core Data名詞解釋

很多的CoreData功能依賴于你創(chuàng)建的一個(gè)數(shù)據(jù)庫(kù)對(duì)象集合(Schema),這個(gè)集合用來(lái)描述應(yīng)用中的實(shí)體(Entity)、字段、和它們之間的關(guān)系。CoreData使用一個(gè)NSManagedObjectModel的實(shí)例作為Schema。一般來(lái)說(shuō),這個(gè)模型越豐富,CoreData越能更好地支持你的應(yīng)用。

一個(gè)對(duì)象模型(managed object model)讓CoreData可以從持久化存儲(chǔ)中匹配一個(gè)你在應(yīng)用中使用的記錄,并轉(zhuǎn)化為數(shù)據(jù)(managed object)。這個(gè)模型是一個(gè)表(Entity Description)的集合(NSEntityDescription的實(shí)例)。一個(gè)Entity Description描述了一個(gè)Entity(你可以想象成一個(gè)在數(shù)據(jù)庫(kù)里面的表)明確的名稱、在應(yīng)用中用來(lái)表示這個(gè)Entity的類和擁有的屬性(字段和關(guān)系)。

創(chuàng)建一個(gè)Entity和設(shè)置它的屬性

創(chuàng)建一個(gè)新的項(xiàng)目并打開模板選擇對(duì)話框的時(shí)候,勾選使用CoreData的選項(xiàng)。一個(gè)CoreData模型文件作為這個(gè)模板的一部分將會(huì)被自動(dòng)創(chuàng)建。這個(gè)源文件后綴為.xxcdatamodeld。打開這個(gè)文件可以看到CoreData模型編輯器。

創(chuàng)建一個(gè)Entity

  1. 點(diǎn)擊“Add Entity”。
    一個(gè)新的未命名Entity會(huì)出現(xiàn)在導(dǎo)航欄Entity列表中。
  2. 選擇這個(gè)新的未命名Entity。
  3. 輸入名稱并回車。

為這個(gè)Entity創(chuàng)建屬性和關(guān)系

  1. 當(dāng)這個(gè)Entity被選中的時(shí)候,在相應(yīng)的編輯框點(diǎn)擊底部的加號(hào)(+)。
    一個(gè)新的未命名屬性或者關(guān)系(其實(shí)也是一個(gè)屬性)為被自動(dòng)添加在屬性或者關(guān)系編輯器上。
  2. 選擇新的未命名屬性。
    這個(gè)屬性配置會(huì)顯示在數(shù)據(jù)模型指示框上。
  3. 給這個(gè)屬性設(shè)置一個(gè)名稱并回車。
    這個(gè)屬性或關(guān)系的信息會(huì)顯示在編輯區(qū)域。

圖2-1表示有一個(gè)叫Employee的Entity,并有以下屬性來(lái)描述這個(gè)Entity:出生日期、名字、入職日期。

圖2-1 Xcode數(shù)據(jù)模型表及其中的Employee Entity

img
img

這時(shí)候你已經(jīng)創(chuàng)建了一個(gè)Entity,但是你還沒(méi)有任何數(shù)據(jù)。數(shù)據(jù)會(huì)在啟動(dòng)應(yīng)用之后創(chuàng)建。在應(yīng)用內(nèi),這些Entity被被用來(lái)創(chuàng)建托管對(duì)象(NSManagedObject實(shí)例)。

配置一個(gè)Entity

現(xiàn)在你已經(jīng)為一個(gè)Entity命了名,你可以在數(shù)據(jù)模型配置器中進(jìn)步一配置這個(gè)Entity。

圖2-2 在數(shù)據(jù)模型配置器中的Entity選項(xiàng)

img
img

Entity名稱和類名

要注意Entity名和類名(一個(gè)NSManagedObject的子類)并不是一樣的。數(shù)據(jù)模型中的Entity結(jié)構(gòu)并不需要跟類層次結(jié)構(gòu)相匹配。圖2-2表示了一個(gè)使用了Objective-C類命名模式的的類名,帶有一個(gè)MO后綴。Entity名和類名是強(qiáng)制要求的。

抽象Entity

如果你不想創(chuàng)建任何Entity實(shí)例你可以指定一個(gè)Entity為抽象的。典型的,如果你有幾個(gè)Entity,這些Entity均表示(繼承自)同一個(gè)公共、不需要自己實(shí)例化Entity,你可以讓此公共Entity變成抽象的。例如,在Employee Entity中你可以定義一個(gè)Person作為一個(gè)抽象Entity,這樣就只能實(shí)例化子Entity(Employee和Customer)。在數(shù)據(jù)模型配置框的Entity框配置了一個(gè)抽象Entity之后,你就告訴了CoreData這個(gè)Entity永遠(yuǎn)不會(huì)被實(shí)例化。

Entity繼承

Entity的繼承類似于類的繼承,同樣十分有用。如果你有許多相似的Entity,你可以提取相同的屬性到超Entity(Super Entity)中,就是父Entity(Parent Entity)。相比起在幾個(gè)Entity中同時(shí)制定相同的屬性,你可以在一個(gè)Entity中定義一遍,子Entity就能繼承它們。例如,你可以定義一個(gè) "Person" Entity,擁有叫“firstName”和“l(fā)astName”的屬性,和它的子Entity “Employee”和“Customer”,繼承了以上屬性。圖2-3闡述了這個(gè)例子??梢栽谟蚁陆寝D(zhuǎn)換編輯器類型之后顯示Entity的圖表結(jié)構(gòu)。

在很多時(shí)候,你可以實(shí)現(xiàn)一個(gè)代表父Entity的自定義類。比起在多個(gè)類中實(shí)現(xiàn)多次類似的業(yè)務(wù)邏輯,你可以在一個(gè)類中完成即可。

注意
在使用SQLite數(shù)據(jù)庫(kù)的時(shí)候要十分小心地使用Entity繼承。所有繼承自一個(gè)Entity的Entity數(shù)據(jù)都會(huì)存在同一個(gè)表。這個(gè)SQLite的特性會(huì)導(dǎo)致性能問(wèn)題。  

圖2-3 Entity繼承圖

img
img

定義字段和關(guān)系

一個(gè)Entity的屬性就是它的字段和關(guān)系,包括了繼承來(lái)的屬性(如果有的話)。除了別的特性之外,每個(gè)屬性都有一個(gè)名字和類型。一個(gè)屬性名字不能是任何NSObject、NSManagedObject的無(wú)參數(shù)方法名。例如,你不能給一個(gè)屬性命名為“description”(詳見(jiàn)NSPropertyDescription)。

臨時(shí)字段(Transient Attribute)是一個(gè)你在模型中定義了,但是不會(huì)保存到數(shù)據(jù)庫(kù)中的屬性。CoreData也會(huì)跟蹤更新臨時(shí)字段,所以它們會(huì)被保存用來(lái)做撤銷(undo)操作。臨時(shí)字段有很多用法,包括保存計(jì)算值和結(jié)果值。

注意  
如果你撤銷了一個(gè)臨時(shí)字段的更新操作,CoreData不會(huì)調(diào)用setter方法來(lái)恢復(fù)舊值 —— 它會(huì)直接使用之前臨時(shí)保存的值。  

圖2-4 數(shù)據(jù)模型配置器中的字段框

img
img

字段

在CoreData模型編輯器和CoreData模型配置器中可以配置一個(gè)字段。CoreData原生支持多種字段類型,例如string、date和integer(表示NSString、NSDate和NSNumber的實(shí)例)。

你可以指定一個(gè)字段是可選的,這樣就表示這個(gè)字段不是非空的。然而一般來(lái)說(shuō),不提倡這樣做,特別是數(shù)字類型的。更好的做法是,你也可以給強(qiáng)制字段設(shè)置一個(gè)默認(rèn)值——在字段中設(shè)置——0.這是因?yàn)樵赟QLite中,NULL的匹配和值對(duì)比不同于Objective-C的nil。NULL在數(shù)據(jù)庫(kù)中不同于0,用0搜索是不能匹配到列為NULL的數(shù)據(jù)的。更進(jìn)一步,NULL在數(shù)據(jù)庫(kù)中不等同于空字符串或者空數(shù)據(jù)。

關(guān)系(Relationsthip)和Fetched屬性(Fetched Property)

在CoreData模型編輯器中可以定義一個(gè)關(guān)系,在數(shù)據(jù)模型配置器中可以指定這個(gè)關(guān)系的值。

圖2-5 數(shù)據(jù)模型配置器中的關(guān)系

img
img

CoreData支持一對(duì)一和一對(duì)多的關(guān)系和Fetched屬性。Fetched屬性表示弱引用(weak)、單指向(one-way)關(guān)系。在employee和department中,department的fetched屬性可以是“recent hires”(employee中沒(méi)有這個(gè)“recent hires”的關(guān)系反轉(zhuǎn)映射)。

關(guān)系類型域中定義了這個(gè)關(guān)系是一個(gè)一對(duì)一還是一對(duì)多關(guān)系。關(guān)系是單向定義。如果是定義一對(duì)多關(guān)系,你需要定義創(chuàng)建兩個(gè)一對(duì)多關(guān)系,并且設(shè)置它們?yōu)橄嗷シ聪蜿P(guān)系。

目標(biāo)域(Destination field)定義了哪個(gè)對(duì)象或者對(duì)象集合在代碼中會(huì)被訪問(wèn)。如果這個(gè)關(guān)系定義為了一個(gè)一對(duì)一關(guān)系,會(huì)返回一個(gè)對(duì)象(或者nil,如果這個(gè)關(guān)系是可選的)。如果這個(gè)關(guān)系定為了一個(gè)一對(duì)多關(guān)系,那么會(huì)返回一個(gè)set(或者nil)。

反向域(Inverse field)定義了關(guān)系的另一半范疇。因?yàn)槊恳粋€(gè)關(guān)系設(shè)置都是單向的,所以這個(gè)域會(huì)綁定兩個(gè)互相指向的關(guān)系。

更多關(guān)于關(guān)系的細(xì)節(jié)可以參照 Creating Managed Object Relationships。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容