初識Core Data
“一個龐然大物,膚色黝黑,面無表情,應(yīng)該不好相處。”這是Core Data給我的第一印象。但據(jù)說它會給別人提供很多的服務(wù),頓時讓我感到一股濃濃的PY味道。為了重返仙界,我也顧不了太多,脫了衣服對它說:“來的匆忙,見面禮沒來得及買。”沒想到它到夠仗義:“既然是Runtime的兄弟,那也就是我的兄弟,不要見外,趕緊穿上衣服,一會兒先帶你去洗個澡,算是為你接風(fēng)了。”
來找Core Data當(dāng)然不是為了瀟灑,第二天,我便向它請教了一些問題。
數(shù)據(jù)類型
Core Data是用來管理數(shù)據(jù)持久化存儲的,其中Transformable數(shù)據(jù)類型比較特別,是用來描述OC中任何類對象的。這么說有點別扭,直接舉例:我們可以用這個類型保存UILabel類對象,也可以是自定義的類對象,只要實現(xiàn)了NSCoding協(xié)議即可,這簡直就是酷炫吊炸天。
每個屬性的設(shè)置選項
- Indexed選項是系統(tǒng)用來提升搜索效率的,但在底層的持久存儲區(qū)中會額外的占用內(nèi)存空間,大小視數(shù)據(jù)量而定,這是典型的用空間換取時間的做法;同時Indexed減慢了數(shù)據(jù)插入和刪除的速度,因為每次插入和刪除都需要更新Indexed,Indexed越多,性能下降越大。具體的取舍,要根據(jù)業(yè)務(wù)需求來定。
- 當(dāng)數(shù)據(jù)類型是Binary Data時,若我們選擇了Allows External Storage選項,Core Data就會把比較大的數(shù)據(jù)(超過1MB)保存在SQLite持久存儲區(qū)域外了,如保存照片、音頻、視頻等。這樣做的目的當(dāng)然是為了提高數(shù)據(jù)存取效率。
關(guān)系
關(guān)系型數(shù)據(jù)庫早就聽說過,就是多個數(shù)據(jù)表之間可以有引用關(guān)系。Core Data所說的關(guān)系也大同小異。使用關(guān)系可以大幅降低數(shù)據(jù)所占用的存儲空間。
在Xcode中我們可以設(shè)置關(guān)系的Type字段為To One或者To Many,如果設(shè)置了To Many,則在生成的NSManagedObject子類中,相關(guān)屬性類型為NSSet(無序且沒有重復(fù)元素的集合);若還選擇了Ordered選項,則相關(guān)屬性類型為NSOrderedSet(有序且沒有重復(fù)元素的集合)。
假如有Department與Personnel兩個實體,之間的關(guān)系如圖:
還有一個對關(guān)系有重要描述的字段Delete Rule,它有4個選項:
- No Action 這個刪除規(guī)則很少使用,它會導(dǎo)致關(guān)系對象處于不一致的狀態(tài)。例如刪除了某個Personnel對象,但是Department對象仍有指向這個Personnel對象的關(guān)系,這就需要手動的去設(shè)置實時的關(guān)系,以確保彼此都指向有效的對象。
- Nullify 這個刪除規(guī)則使有關(guān)系的對象之間失去關(guān)系,但雙方仍都存在。例如把Personnel實體中的關(guān)系的刪除規(guī)則設(shè)置為Nullify,則刪除某個Personnel對象后,它就與Department對象沒有關(guān)系了,但是這個Personnel對象仍然存在,這時候就可以將此對象再關(guān)聯(lián)到其他的Department對象上,完成關(guān)系的轉(zhuǎn)移。
- Cascade 這個刪除規(guī)則會沿著關(guān)系來傳播刪除操作。例如把Department實體中的關(guān)系的刪除規(guī)則設(shè)置為Cascade,則刪除某個Department對象后,與它有關(guān)系的Personnel對像也都會被刪除。
- Deny 這個刪除規(guī)則在有關(guān)系的對象之間產(chǎn)生一個約束(某種情況拒絕刪除操作)。例如把Department實體中的關(guān)系的刪除規(guī)則設(shè)置為Deny,那么當(dāng)刪除某個Department對象并試圖將改動保存時,若仍有Personnel對象與之有關(guān)系,則會引發(fā)validation error(cocoa error 1600)。所以當(dāng)采用了Deny規(guī)則,在刪除對象前就要確保沒有關(guān)系對象再與之有關(guān)聯(lián)了。
??只有在調(diào)用了save:
方法后,系統(tǒng)才會去實施刪除規(guī)則。
為了避免程序崩潰,在刪除規(guī)則為Deny時,進行刪除操作前可以先調(diào)用NSManagedObject中的validateForDelete:
方法去判斷是否能夠安全的刪除對象。
NSError *error;
if ([oneDepartment validateForDelete:&error]) {
[_context deleteObject:oneDepartment];
} else {
NSLog(@"Failed to delete %@, Error: %@", oneDepartment, error.localizedDescription);
}
Core Data告訴我,掌握了這些招式,就可以繼續(xù)踏上修仙的大道了。我心里想,就這么點把戲,就打發(fā)我走嗎?但礙于在別人屋檐下,我只好低頭,于是決定給它點甜頭嘗嘗。
關(guān)注微信公眾號CodingArtist,可以第一時間得到文章更新通知! _