CoreData 從入門到精通 (一) 數(shù)據(jù)模型 + CoreData 棧的創(chuàng)建

CoreData 從入門到精通 (一) 數(shù)據(jù)模型 + CoreData 棧的創(chuàng)建

概述

CoreData 是 Cocoa 平臺(tái)上用來管理模型層數(shù)據(jù)和數(shù)據(jù)持久化的一個(gè)框架歇僧,說簡(jiǎn)單點(diǎn)擂达,就是一個(gè)數(shù)據(jù)庫(kù)存儲(chǔ)框架番刊。CoreData 里相關(guān)的概念比較多忙芒,而且初始化也非常繁瑣,所以對(duì)初學(xué)者的學(xué)習(xí)還是有一些困難的。這篇文章將從頭到尾詳細(xì)地講一遍 CoreData 的使用方法,從 CoreData 的初始化到簡(jiǎn)單的增刪改查奄薇,再到批量處理,數(shù)據(jù)模型的版本更新以及和 TableView 的結(jié)合等抗愁,真正讓你能徹底了解 CoreData馁蒂。

一、CoreData 數(shù)據(jù)模型的創(chuàng)建

想要使用 CoreData 蜘腌,第一部是是創(chuàng)建數(shù)據(jù)模型沫屡,它描述了數(shù)據(jù)的結(jié)構(gòu)和關(guān)聯(lián)關(guān)系等〈橹椋可以理解為數(shù)據(jù)庫(kù)中的表結(jié)構(gòu)沮脖。在 Xcode 創(chuàng)建工程時(shí),提供了創(chuàng)建 CoreData 的模板,只需要我們?cè)趧?chuàng)建時(shí)勺届,勾選 CoreData 選項(xiàng)驶俊,Xcode 就會(huì)自動(dòng)創(chuàng)建出數(shù)據(jù)模型文件:

use coredata

它是一個(gè) .xcdatamodeld 格式的文件:

Coredata-2

如果創(chuàng)建時(shí)沒有勾選 CoreData,當(dāng)然也可以在 File -> new -> file 里手動(dòng)添加這個(gè)文件:

CoreData-3

然后打開這個(gè)文件涮因,是這樣的:

DataModel

點(diǎn)擊下面的 Add Entity 按鈕可以添加一個(gè)Entity废睦,也就是一個(gè)數(shù)據(jù)實(shí)體,相當(dāng)于數(shù)據(jù)庫(kù)中的一張表:

AddEntity

點(diǎn)擊添加一個(gè) Student 的 Entity:

StudentEntity

圖中的 Attributes 是定義屬性的地方养泡,Relationships 是定義關(guān)聯(lián)關(guān)系的地方嗜湃,點(diǎn)擊加號(hào)可以添加。下面來給 Student 添加三個(gè)字段:studentName, studentAge, studentId:

studentEntity2

下面是 CoreData 里支持的數(shù)據(jù)類型:

DataType

選中一個(gè)字段澜掩,可以在右側(cè)的面板中對(duì)它做一些自定義:

DataType2

例如在 validation 里對(duì)數(shù)據(jù)做一些限制购披,字符串的長(zhǎng)度,數(shù)字類型的最大最下值肩榕;設(shè)置索引刚陡、默認(rèn)值等。不同的數(shù)據(jù)類型可以設(shè)置不同的內(nèi)容株汉,一般維持默認(rèn)就可以筐乳。

另外對(duì)于每一個(gè) entity 實(shí)體類,Build 過后 Xcode 都會(huì)自動(dòng)幫我們生成相應(yīng)的實(shí)體類代碼乔妈,生成的代碼不會(huì)在工程目錄中顯示出來蝙云,但是可以通過導(dǎo)入頭文件索引到;當(dāng)然也可以配置成手動(dòng)生成的路召,選中對(duì)應(yīng)的 Entity 然后點(diǎn)擊右側(cè)面板的 Codegen勃刨,把 ClassDefinition 修改成 Manual/None,然后 Xcode 就不會(huì)再自動(dòng)生成了股淡。

Codegen

另外身隐,Xcode 自動(dòng)生成的代碼都是 Swift 語(yǔ)言的,如果想改成Objc唯灵,可以在這里改:

ChangeCodegen

這個(gè)時(shí)候也可以通過 Editor -> Create NSManagedObject Subclass 來生成相應(yīng)的實(shí)體類:

CreateNSObjSubclass

需要注意的是贾铝,如果前面有自動(dòng)生成過這些類文件,手動(dòng)生成后可能會(huì)編譯出錯(cuò)埠帕,因?yàn)楣こ汤飼?huì)索引到兩份同樣的代碼忌傻,這個(gè)時(shí)候需要 Clean 一下工程再 Build 即可。

下面是自動(dòng)生成的實(shí)體類:

EntityClass1
EntityClass1

到此為止搞监,CoreData 的數(shù)據(jù)模型就創(chuàng)建好了水孩。

二、CoreData 棧的創(chuàng)建

數(shù)據(jù)模型創(chuàng)建好之后琐驴,想要使用 CoreData 進(jìn)行數(shù)據(jù)持久化俘种,下一步就是初始化 CoreData 棧了秤标。下面是蘋果文檔里對(duì) CoreData 棧的介紹:

The Core Data stack is a collection of framework objects that are accessed as part of the initialization of Core Data and that mediate between the objects in your application and external data stores.

CoreData 棧是 CoreData 初始化被訪問的框架對(duì)象的集合,以及應(yīng)用中數(shù)據(jù)對(duì)象和外部數(shù)據(jù)存儲(chǔ)的媒介宙刘。CoreData 的初始化需要一步步地初始化 CoreData 棧上的三個(gè)對(duì)象結(jié)構(gòu)苍姜,它們分別是:

  1. NSManagedObjectModel — 描述了數(shù)據(jù)模型的結(jié)構(gòu)信息
  2. NSPersistentStoreCoordinator — 數(shù)據(jù)持久層和內(nèi)存對(duì)象模型的協(xié)調(diào)器
  3. NSManagedObjectContext — 內(nèi)存中 managedObject 對(duì)象的上下文

下圖是 CoreData 棧的結(jié)構(gòu),圖片來自 objc.io 的圖書 《CoreData》:

CoreDataStack

下面來用代碼演示 CoreData 棧的初始化過程:

1悬包、加載 ManagedObjectModel

第一步是創(chuàng)建 NSManagedObjectModel 對(duì)象衙猪,它需要通過上文中講的數(shù)據(jù)模型文件來創(chuàng)建:

@interface Appdelegate ()
  
@property (nonatomic, readwrite, strong) NSManagedObjectModel *managedObjectModel;
  
@end
  
@implementation
  // 使用懶加載的方式初始化
- (NSManagedObjectModel *)managedObjectModel {
    if (!_managedObjectModel) {
      // url 為CoreDataDemo.xcdatamodeld,注意擴(kuò)展名為 momd布近,而不是 xcdatamodeld 類型
        NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreDataDemo" withExtension:@"momd"];
        _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    }
    return _managedObjectModel;
}

@end

2垫释、創(chuàng)建 PersistentStoreCoordinator

創(chuàng)建好 managedObjectModel 后就可以來創(chuàng)建 persistentStoreCoordinator 了,因?yàn)樗膭?chuàng)建需要用到 managedObjectModel撑瞧,managedObjectModel 告訴了persistentStoreCoordinator 數(shù)據(jù)模型的結(jié)構(gòu)棵譬,然后 persistentStoreCoordinator 會(huì)根據(jù)對(duì)應(yīng)的模型結(jié)構(gòu)創(chuàng)建持久化的本地存儲(chǔ)。

@interface AppDelegate ()

@property (nonatomic, readwrite, strong) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, readwrite, strong) NSPersistentStoreCoordinator *persistentStoreCoordinator;

@end

@implementation AppDelegate

- (NSManagedObjectModel *)managedObjectModel {
    if (!_managedObjectModel) {
        NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreDataDemo" withExtension:@"momd"];
        _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    }
    return _managedObjectModel;
}
// 同樣使用懶加載創(chuàng)建
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    if (!_persistentStoreCoordinator) {
        // 創(chuàng)建 coordinator 需要傳入 managedObjectModel
        _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];
      // 指定本地的 sqlite 數(shù)據(jù)庫(kù)文件
        NSURL *sqliteURL = [[self documentDirectoryURL] URLByAppendingPathComponent:@"CoreDataDemo.sqlite"];
        NSError *error;
      // 為 persistentStoreCoordinator 指定本地存儲(chǔ)的類型预伺,這里指定的是 SQLite
        [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                  configuration:nil
                                                            URL:sqliteURL
                                                        options:nil
                                                          error:&error];
        if (error) {
            NSLog(@"falied to create persistentStoreCoordinator %@", error.localizedDescription);
        }
    }
    return _persistentStoreCoordinator;
}

// 用來獲取 document 目錄
- (nullable NSURL *)documentDirectoryURL {
    return [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].firstObject;
}

@end

3订咸、創(chuàng)建 ManagedObjectContext

上面兩步都完成之后,下面來創(chuàng)建 managedObjectContext, 這也是平時(shí)操作 CoreData 主要會(huì)用到的對(duì)象:

@interface
...
@property (nonatomic, readwrite, strong) NSManagedObjectContext *context;
...
@end
@implementation
 ...
  
- (NSManagedObjectContext *)context {
    if (!_context) {
      // 指定 context 的并發(fā)類型: NSMainQueueConcurrencyType 或 NSPrivateQueueConcurrencyType
        _context = [[NSManagedObjectContext alloc ] initWithConcurrencyType:NSMainQueueConcurrencyType];
        _context.persistentStoreCoordinator = self.persistentStoreCoordinator;
    }
    return _context;
}
...
@end

至此酬诀,CoreData 棧的初始化就創(chuàng)建完成了脏嚷。以后操作 CoreData 就可以通過 context 屬性來完成,操作完之后調(diào)用 contextsave 方法就可以數(shù)據(jù)持久化到本地瞒御。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末然眼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子葵腹,更是在濱河造成了極大的恐慌,老刑警劉巖屿岂,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件践宴,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡爷怀,警方通過查閱死者的電腦和手機(jī)阻肩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來运授,“玉大人烤惊,你說我怎么就攤上這事∮蹼” “怎么了柒室?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)逗宜。 經(jīng)常有香客問我雄右,道長(zhǎng)空骚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任擂仍,我火速辦了婚禮囤屹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘逢渔。我一直安慰自己肋坚,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布肃廓。 她就那樣靜靜地躺著智厌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪亿昏。 梳的紋絲不亂的頭發(fā)上峦剔,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音角钩,去河邊找鬼吝沫。 笑死,一個(gè)胖子當(dāng)著我的面吹牛递礼,可吹牛的內(nèi)容都是我干的惨险。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼脊髓,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼辫愉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起将硝,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤恭朗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后依疼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體痰腮,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年律罢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了膀值。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡误辑,死狀恐怖沧踏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情巾钉,我是刑警寧澤翘狱,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站砰苍,受9級(jí)特大地震影響盒蟆,放射性物質(zhì)發(fā)生泄漏踏烙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一历等、第九天 我趴在偏房一處隱蔽的房頂上張望讨惩。 院中可真熱鬧,春花似錦寒屯、人聲如沸荐捻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)处面。三九已至,卻和暖如春菩掏,著一層夾襖步出監(jiān)牢的瞬間魂角,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工智绸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留野揪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓瞧栗,卻偏偏與公主長(zhǎng)得像斯稳,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子迹恐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容