Core Data學(xué)習(xí)筆記二:創(chuàng)建NSManagedObject對(duì)象

NSManagedObject

上篇文章Core Data學(xué)習(xí)筆記一:創(chuàng)建CoreDataStack創(chuàng)建了Data Model 文件,并且創(chuàng)建了一些實(shí)例Entity 如果說(shuō),可視化Data Model文件在程序中,對(duì)應(yīng)了NSManagedModel對(duì)象,這些Entity在程序中,所對(duì)應(yīng)的對(duì)象就是NSManagedObject (當(dāng)然其實(shí)并不完全對(duì)等,可以先這么理解)

Document

NSManagedObject is a generic class that implements all the basic behavior required of a Core Data model object. It is not possible to use instances of direct subclasses of NSObject (or any other class not inheriting from NSManagedObject) with a managed object context. You may create custom subclasses of NSManagedObject, although this is not always required. If no custom logic is needed, a complete Object graph can be formed with NSManagedObject instances.

這里大概有三個(gè)要點(diǎn)

  • NSManagedObject 代表了Data Model中的對(duì)象
  • NSManagedObject 需要和 NSManagedObjectContext 結(jié)合使用才有意義
  • NSManagedObject 滿足所有你自定義的model 對(duì)象需求,通過(guò)KVC 去訪問(wèn)相應(yīng)的屬性

生成NSManagedObject子類

雖然通過(guò)KVC就可以訪問(wèn)NSManagedObject所有的屬性,但這樣使用起來(lái)不是很方便。

在Xcode Data Model Editor 中選中你要?jiǎng)?chuàng)建NSManagedObject子類的實(shí)例,在右側(cè)Data Model Inspector中選擇Codegen

1.png
  • Manual/None
  • Category/Extension.
  • Class Definition

Manual/None is the default, and previous behavior; in this case you should implement your own subclass or use NSManagedObject.

這個(gè)是iOS10以前的默認(rèn)行為,需要我們手動(dòng)通過(guò)Xcode Editor-> Create NSManagedObject SubClass... 生成ClassName+CoreDataClass 文件以及 ClassName+CoreDataGeneratedProperties 其中前者,是類的定義,以及類行為定義,后者通過(guò)category 定義了類的屬性(注:Objective-C中Category定義屬性不支持生成成員變量,但可以生成get set 方法,CoreData屬性通過(guò)@dynamic修飾,表示,運(yùn)行時(shí)生成 get set 方法)

當(dāng)每次修改,data model的時(shí)候,重新通過(guò)以上方法,生成NSManagedObject對(duì)象,系統(tǒng)只會(huì)覆蓋ClassName+CoreDataGeneratedProperties文件,而不會(huì)修改ClassName+CoreDataClass 文件。

Category/Extension generates a class extension in a file named like ClassName+CoreDataGeneratedProperties. You need to declare/implement the main class (if in Obj-C, via a header the extension can import named ClassName.h).

一般情況下,因?yàn)槲覀儾恍枰薷膶傩訡ategory的定義,而只需要修改類行為的定義,所以這個(gè)選項(xiàng),就直接不對(duì)開發(fā)者暴露Category 文件,當(dāng)你修改了DataModel的時(shí)候,就可以自動(dòng)同步最新的代碼

Class Definition generates subclass files named like ClassName+CoreDataClass as well as the files generated for Category/Extension.

當(dāng)我們也不需要為NSManagedObject定義行為的時(shí)候,我們就可以選中這個(gè)選項(xiàng),然后直接在項(xiàng)目里引用頭文件就可以直接使用。

數(shù)據(jù)庫(kù) 增刪改查

增加一個(gè)數(shù)據(jù)庫(kù)對(duì)象,首先,需要?jiǎng)?chuàng)建一個(gè)NSEntityDescription,前面說(shuō) Data Model Editor 里的實(shí)例并不完全和NSManagedObject對(duì)等,就是因?yàn)閯?chuàng)建NSManagedObject對(duì)象,還需要entity相關(guān)的描述對(duì)象,這個(gè)對(duì)象才與實(shí)例對(duì)等。

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Doge" inManagedObjectContext:_context];
Doge *doge = [[Doge alloc] initWithEntity:entity insertIntoManagedObjectContext:_context];
doge.name = @"xxx";
...
...
//注意,這里并沒有實(shí)際把對(duì)象存入數(shù)據(jù)庫(kù),實(shí)際存入需要調(diào)用NSManagedObjectContext 的save:方法
[_context save:nil];

直接訪問(wèn)NSManagedObject屬性的set方法,就可以修改屬性,同時(shí),也只有當(dāng)調(diào)用了NSManagedObjectContext 的-save:方法后才能存入實(shí)際的存儲(chǔ)文件中

刪除調(diào)用NSManagedObjectContext-deleteObject:方法,然后調(diào)用-save:方法

 Doge *doge = ...
 [_context deleteObject:doge];
 [_context save:nil]

查 會(huì)單獨(dú)寫一篇學(xué)習(xí)筆記:)

Demo

添加數(shù)據(jù)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    [self importSeedJsonSeedIfNeeded];
    return YES;
}
- (void)importSeedJsonSeedIfNeeded {
    
    NSManagedObjectContext *context = [[MTCoreDataStack sharedInstance] managedContext];
    
    NSFetchRequest * fetchRequest = [Master fetchRequest];
    fetchRequest.resultType = NSCountResultType;
    
    NSError *error;
    NSArray *results = [context executeFetchRequest:fetchRequest error:&error];
    if (!error) {
        if ([results count] > 0) {
            NSInteger masterCount = [[results objectAtIndex:0] integerValue];
            if (masterCount <= 0) {
                [self importJsonSeed];
            }
        } else {
            [self importJsonSeed];
        }
        
    }else {
        [self importJsonSeed];
    }
    
}

- (void)importJsonSeed {
    NSURL *jsonURL = [[NSBundle mainBundle] URLForResource:@"seed" withExtension:@"json"];
    
    NSError *error;
    NSData *jsonData = [NSData dataWithContentsOfURL:jsonURL options:0 error:&error];
    
    if (!error) {
        NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
        if (!error) {
            
            NSManagedObjectContext *context = [[MTCoreDataStack sharedInstance] managedContext];
            
            NSEntityDescription *masterEntity = [NSEntityDescription entityForName:@"Master" inManagedObjectContext:context];
            NSEntityDescription *dogeEntity = [NSEntityDescription entityForName:@"Doge" inManagedObjectContext:context];
            
            NSDictionary *masterDict = jsonDict[@"master"];
            if (![masterDict isKindOfClass:[NSDictionary class]]) {
                return;
            }
            
            Master *master = [[Master alloc] initWithEntity:masterEntity insertIntoManagedObjectContext:context];
            master.name = masterDict[@"name"];
            master.age = [masterDict[@"age"] integerValue];
        
            NSArray *doges = jsonDict[@"doges"];
            
            for (NSDictionary *dogeDict in doges) {
                if (![dogeDict isKindOfClass:[NSDictionary class]]) {
                    continue;
                }
                Doge *doge = [[Doge alloc] initWithEntity:dogeEntity insertIntoManagedObjectContext:context];
                doge.name = dogeDict[@"name"];
                doge.age = [dogeDict[@"age"] integerValue];
                doge.master = master; //因?yàn)樵贒ataModel 里設(shè)置了 inverse, 所以master 和 doge可以相互關(guān)聯(lián)上
            }
            //一定要調(diào)用 save 方法,才能真正的將文件存入數(shù)據(jù)庫(kù)
            [[MTCoreDataStack sharedInstance] saveContext];
        }
    }
}

源碼下載

https://github.com/mengtian-li/CoreDataStackDemo/releases/tag/v0.2

最后編輯于
?著作權(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)容

  • 本文是對(duì) MagicalRecord github上的翻譯 正文:注意: MagicalRecord 在 ARC...
    騂躍神話閱讀 2,136評(píng)論 1 5
  • 適讀對(duì)象: 需要入門Core Data的朋友; 像我一樣,尚未學(xué)過(guò)數(shù)據(jù)庫(kù)相關(guān)課程,不太懂怎么寫SQLite語(yǔ)句的朋...
    AntonyWong閱讀 5,636評(píng)論 8 21
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,554評(píng)論 19 139
  • 2017年不知不覺走到了尾聲,僅剩最后一個(gè)月,似乎大家都開始慌亂了,回看年初的計(jì)劃,實(shí)現(xiàn)了多少呢? 不管過(guò)去的11...
    田心小妹閱讀 1,095評(píng)論 2 5
  • 春 東風(fēng)隱沒沉沉的夢(mèng) 手指觸不到似曾相識(shí)的臉 夜空驚現(xiàn)幾聲驚雷 想必這便是怦然心動(dòng)的朗春 夏 暖風(fēng)吹開楊柳綠 帶來(lái)...
    概念系閱讀 290評(píng)論 0 0

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