背景
近期公司項(xiàng)目需要本地持久化保存一些用戶信息數(shù)據(jù),由于數(shù)據(jù)量的問(wèn)題還有無(wú)需刪除后保留,選擇了使用數(shù)據(jù)庫(kù)來(lái)保存這些信息。iOS數(shù)據(jù)庫(kù)使用,大致有FMDB、WCDB、CoreData、Relam等,本次使用CoreData進(jìn)行數(shù)據(jù)留存,作為隨筆,后續(xù)其他數(shù)據(jù)庫(kù)相關(guān)在后續(xù)學(xué)習(xí)中再行添加更新。
CoreData
CoreData是Apple 提供的一個(gè)用來(lái)管理輕量化數(shù)據(jù)庫(kù)的框架,這個(gè)框架可以在單個(gè)設(shè)備上,本地化保存app的永久數(shù)據(jù)、緩存暫時(shí)數(shù)據(jù)、以及對(duì)數(shù)據(jù)的撤銷操作等,使用CoreData,我們無(wú)需直接對(duì)數(shù)據(jù)庫(kù)進(jìn)行sql的語(yǔ)法操作,通過(guò)CoreData來(lái)在運(yùn)行時(shí)中管理,CoreData通過(guò)抽象你的對(duì)象到存儲(chǔ)區(qū)映射的細(xì)節(jié),使得app能更簡(jiǎn)單的管理數(shù)據(jù),無(wú)需直接操縱數(shù)據(jù)庫(kù)。
CoreData創(chuàng)建
創(chuàng)建項(xiàng)目時(shí)勾上CoreData(Tip:也可以自己后續(xù)添加)

左側(cè)文件樹(shù)目錄會(huì)出現(xiàn)一個(gè).xcdatamodeld的文件,這個(gè)文件就是我們創(chuàng)建entity、建表、操作屬性的地方。打開(kāi)該文件。

如圖,左側(cè)列表為我們?cè)谠撃P臀募械模?code>Entites 實(shí)體、Fetch Requests 請(qǐng)求模板、Configurations 配置信息,可以通過(guò)左下角加號(hào)按鈕進(jìn)行分別添加。
Entity
添加entity后,右側(cè)列表中展示了該entity的具體結(jié)構(gòu)信息,分為三部分:Attributes 屬性、Relationships 關(guān)聯(lián)、Fetched Properties 獲取操作。
-
Attributes
Attributes即為實(shí)體屬性,我們需要為存儲(chǔ)的屬性創(chuàng)建對(duì)應(yīng)的鍵,包括名字以及類型。這里介紹一下具體的屬性類型以及一般我們常用的一些類型:- String: 字符串,在對(duì)應(yīng)的類文件中以
NSSString表示 - Boolean: 布爾值,以
NSNumber表示 - Float: 單精度浮點(diǎn)小數(shù)
- Double: 雙精度浮點(diǎn)小數(shù)
- Integer16 32 64: 整數(shù),不同的范圍,一般都用16,如果是為枚舉類型而設(shè)立,可以使用16,對(duì)應(yīng)類名中使用
NSNumber,調(diào)用時(shí)記得取intValue即可。 - Date: 時(shí)間,以
NSDate表示 - Binary Data: 二進(jìn)制數(shù)據(jù),以
NSData表示 - Transformable: OC對(duì)象,自動(dòng)創(chuàng)建時(shí)以
id表示,在對(duì)應(yīng)的類文件中,我們可以改為具體的OC類名,但是該對(duì)象必須遵守NSCoding協(xié)議。
- String: 字符串,在對(duì)應(yīng)的類文件中以
-
Relationships
Relationships為實(shí)體關(guān)聯(lián)關(guān)系,顧名思義可將不同實(shí)體建立聯(lián)系,CoreData會(huì)在該實(shí)體下一個(gè)屬性,將之與被關(guān)聯(lián)的實(shí)體所對(duì)應(yīng)的屬性關(guān)聯(lián)起來(lái)。如圖所示:
FD3B4F26-EE88-4AAD-AC6B-D65B7246D315.png
Destination表明為目標(biāo)關(guān)聯(lián)實(shí)體,Inverse表明為對(duì)應(yīng)的關(guān)系,這樣將一個(gè)addressmodel添加進(jìn)accountmodel的同時(shí),該addressmodel的relationship也會(huì)自動(dòng)指向accountmodel,雙方形成對(duì)應(yīng)。
8E8E6109-2B6E-4914-8D05-A95464A31DD9.png
熟悉sqlite的朋友,其實(shí)relationship類似于外鍵,定義了實(shí)體之間的關(guān)系,type分為兩種:一對(duì)一、一對(duì)多,對(duì)多關(guān)系的時(shí)候使用NSSet來(lái)存儲(chǔ)模型。 Fetched Properties
定義查詢操作,但我們一般都是在具體代碼環(huán)境下具體定義操作,所以一般不怎么在這里設(shè)置。
- Data Model Inspector
除開(kāi)以上,我們可以對(duì)具體的entity、relationship進(jìn)行一些屬性上的設(shè)置:
對(duì)于attribute:
- default value: 設(shè)置默認(rèn)值,注意二進(jìn)制類型無(wú)法設(shè)置
- optional: 代表可選,如果為NO,在進(jìn)行save操作時(shí)該屬性必須有值,否則返回error,默認(rèn)為YES。
- transient: 設(shè)置當(dāng)前屬性是否只保存在內(nèi)存中,如果為YES,該屬性將不會(huì)被本地持久化,適合用于存儲(chǔ)一些內(nèi)存中緩存的數(shù)據(jù),比如一些臨時(shí)的每次都會(huì)變更的數(shù)據(jù)。
- index: 索引設(shè)置
- Validation:
Validation可以設(shè)置最大值與最小值來(lái)約束數(shù)據(jù),數(shù)值類型為大小,字符串為長(zhǎng)度、時(shí)間為約定時(shí)間。 - Reg.Ex: 正則,設(shè)置正則表達(dá)式來(lái)約束數(shù)據(jù),只用于驗(yàn)證和控制,并不對(duì)數(shù)據(jù)產(chǎn)生影響。
對(duì)于relationship:
- Delete Rule: 刪除規(guī)則,用于規(guī)定,當(dāng)前對(duì)象被刪除后,與之關(guān)聯(lián)的對(duì)象的反應(yīng)
NSNoActionDeleteRule 刪除后無(wú)操作,關(guān)聯(lián)對(duì)象的關(guān)聯(lián)屬性不會(huì)被指向nil,注意此時(shí)再使用關(guān)聯(lián)對(duì)象的關(guān)聯(lián)屬性可能會(huì)出現(xiàn)問(wèn)題。
NSNullifyDeleteRule 刪除后置nil,將關(guān)聯(lián)對(duì)象的關(guān)聯(lián)屬性指向nil,為默認(rèn)設(shè)置
NSCascadeDeleteRule 級(jí)聯(lián)刪除,將關(guān)聯(lián)對(duì)象一起刪除
NSDenyDeleteRule 拒絕刪除,如果當(dāng)前對(duì)象還指向其他關(guān)聯(lián)對(duì)象,則當(dāng)前對(duì)象不能被刪除
對(duì)于entity:
- Parent Entity: 設(shè)置父類實(shí)體,子類會(huì)繼承父類的數(shù)據(jù),但是這些數(shù)據(jù)會(huì)存于父類實(shí)體的表當(dāng)中,當(dāng)多個(gè)子類繼承于同一父類時(shí),所有子類的父類部分都會(huì)存放于父類表中,這里會(huì)有性能問(wèn)題。(繼承屬性名字不要相同)
Fetch Requests
一些更加簡(jiǎn)單直觀的請(qǐng)求配置,一般也不做設(shè)定。
可視化模型
CoreData右下角界面的editor style,可以使我們自由切換表格展示或者是圖形可視化展示,更加輕松的看到實(shí)體與屬性的關(guān)系,實(shí)體與實(shí)體之間的聯(lián)系。如上圖。
創(chuàng)建托管對(duì)象類文件
當(dāng)我們?cè)谀P椭袆?chuàng)建好實(shí)體后,就要根據(jù)實(shí)體,生成我們?cè)诰唧w開(kāi)發(fā)中使用的,基于NSManagedObject類的托管類對(duì)象文件了,我們通過(guò)這類對(duì)象來(lái)進(jìn)行對(duì)數(shù)據(jù)庫(kù)的操作。
xcode為我們提供了自動(dòng)化生成的方式,在菜單欄Editor -> Create NSManagedObject Subclass -> 選擇對(duì)應(yīng)數(shù)據(jù)庫(kù)版本(后續(xù)再說(shuō)數(shù)據(jù)庫(kù)版本相關(guān)) -> 勾選對(duì)應(yīng)要生成托管類的實(shí)體 -> 生成文件。圖略

在左側(cè)文件數(shù)列表可見(jiàn),每個(gè)實(shí)體都對(duì)應(yīng)生成了4個(gè)文件:
分別是以實(shí)體名開(kāi)頭的.h、.m以及實(shí)體的Category文件
托管對(duì)象類文件
以實(shí)體名生成的文件,這個(gè)文件xcode沒(méi)有生成任何多余的代碼,是用來(lái)讓我們添加自己的用來(lái)管理操作數(shù)據(jù)庫(kù)的的相關(guān)邏輯代碼,相當(dāng)于一層單例Manager,我們自己app內(nèi)的增刪改查方法邏輯就寫在這里(app -> CoreData),方法內(nèi)的具體CoreData Api調(diào)用才是操作數(shù)據(jù)庫(kù)的一層(CoreData -> Database)。
如果有設(shè)置relationship,類文件會(huì)聲明@class
Category 分類
點(diǎn)開(kāi)分類,里面有xcode自動(dòng)生成的一系列代碼,包括我們?cè)趚cdatamodeld中設(shè)置的實(shí)體屬性:
如果我們?cè)O(shè)置的relationship的type為一對(duì)多,那么就會(huì)有CoreDataProperties 實(shí)體屬性以及CoreDataGeneratedAccessors 對(duì)多屬性集合方法
前者表明具體實(shí)體的Attributes、Relationships,后者為系統(tǒng)生成的管理對(duì)多方法,都是在運(yùn)行時(shí)中動(dòng)態(tài)實(shí)現(xiàn)的,分類文件可以不管。
前文有提到設(shè)置屬性的類型,xcode為我們自動(dòng)生成的分類文件中,transformalbe的位置是id,需要我們手動(dòng)改寫成我們需要的類名(遵守NSCoding協(xié)議,因?yàn)橐粴w檔),其他數(shù)值類型的默認(rèn)都為NSNumber,當(dāng)然創(chuàng)建托管類對(duì)象文件的時(shí)候可以勾選Use scalar properties for primitive data types來(lái)生成具體對(duì)應(yīng)的標(biāo)量類型屬性,那創(chuàng)建出來(lái)就是具體的比如int_16、double等類型。
注意當(dāng)更新屬性后,要記得重新生成托管類對(duì)象文件?。。?br> 基本的介紹以及創(chuàng)建過(guò)程就是這樣,后續(xù)會(huì)更新CoreData 內(nèi)對(duì)于數(shù)據(jù)庫(kù)的操作!謝謝。
一些小問(wèn)題(更新)
- 當(dāng)我們創(chuàng)建xcdatamodeld的同時(shí),Core Data就已經(jīng)生成了對(duì)應(yīng)的default文件了,只是左側(cè)的文件樹(shù)目錄看不到,這時(shí)候如果我們?cè)偈謩?dòng)生成托管類對(duì)象文件的時(shí)候,編譯器就會(huì)報(bào)重復(fù)錯(cuò)誤,需要在xcddatamodeld中,選擇每個(gè)實(shí)體,將Inspector中的Codegen選項(xiàng),選擇
Manual/None即可

