CoreData

初始化

- (NSManagedObjectContext *)context {
    if (_context == nil) {
        // 創(chuàng)建上下文對象,并發(fā)隊列設(shè)置為主隊列
        _context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        
        // 創(chuàng)建托管對象模型,并使用Student.momd路徑當(dāng)做初始化參數(shù)
        // .xcdatamodeld文件 編譯之后變成.momd文件  (.mom文件)
        NSURL *modelPath = [[NSBundle mainBundle] URLForResource:@"Test" withExtension:@"momd"];
        NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelPath];
        // 創(chuàng)建持久化存儲調(diào)度器
        NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
        // 創(chuàng)建并關(guān)聯(lián)SQLite數(shù)據(jù)庫文件怯伊,如果已經(jīng)存在則不會重復(fù)創(chuàng)建
        NSString *dataPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
        dataPath = [dataPath stringByAppendingFormat:@"/%@.sqlite",@"CPStudent"];
        // 創(chuàng)建
        [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:dataPath] options:options error:nil];
        // 上下文對象設(shè)置屬性為持久化存儲器
        _context.persistentStoreCoordinator = coordinator;
    }
    return _context;
}

- (NSPersistentContainer *)persistentContainer {
    // 如果已經(jīng)存在持久容器,直接返回
    if (_persistentContainer != nil) {
        return _persistentContainer;
    }

    // 創(chuàng)建持久容器,通常與你的數(shù)據(jù)模型同名
    _persistentContainer = [[NSPersistentContainer alloc] initWithName:@"test"];
    
    // 完成持久容器的加載
    [_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) {
        if (error != nil) {
            NSLog(@"Unresolved error %@, %@", error, error.userInfo);
            abort(); // 處理初始化錯誤
        }
    }];
    
    return _persistentContainer;
}

- (void)initCoreData {
    NSPersistentContainer *container = [self persistentContainer];
    [container loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) {
        if (error) {
            NSLog(@"Error loading Core Data store: %@, %@", error, error.userInfo);
            abort(); // 處理初始化錯誤
        }
        
        NSManagedObjectContext *context = [self persistentContainer].viewContext;
        NSManagedObject *newStudent = [NSEntityDescription insertNewObjectForEntityForName:@"newStudent" inManagedObjectContext:context];
        [newStudent setValue:@"liming" forKey:@"name"];
        [newStudent setValue:@(11) forKey:@"age"];
        [newStudent setValue:@(100001) forKey:@"numebr"];

        NSError *addError;
        if (![context save:&addError]) {
            NSLog(@"Error saving context: %@", addError.localizedDescription);
        }
    }];
}

- (CPStudent *)insertStudentData {
    NSError *error = nil;
    
   // 開始創(chuàng)建托管對象,并指明好創(chuàng)建的托管對象所屬實體名
    CPStudent * student = [NSEntityDescription insertNewObjectForEntityForName:@"CPStudent" inManagedObjectContext:self.context];
    
    //2.根據(jù)表Student中的鍵值夫啊,給NSManagedObject對象賦值
    student.name = [NSString stringWithFormat:@"Mr-%d",arc4random() % 100];
    student.age = arc4random() % 20;
    student.sex = arc4random() % 2 == 0 ?  @"男" : @"女" ;
    student.height = arc4random() % 180;
    student.number = arc4random() % 100;
    student.father = @"aaa";
    student.studentNumber = arc4random() % 100;
    
    if ([self.context hasChanges] && ![self.context save:&error]) {
        NSLog(@"Unresolved error %@, %@", error, error.userInfo);
        abort();
        return nil;
    } else {
        NSLog(@"插入數(shù)據(jù)成功");
    }
    
    return student;
}

- (void)delete:(NSArray *)delStudents {
    // 獲取數(shù)據(jù)的請求對象,指明對實體進行刪除操作
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"CPStudent"];
    
    [delStudents enumerateObjectsUsingBlock:^(CPStudent *obj, NSUInteger idx, BOOL *stop) {
        // 通過創(chuàng)建謂詞對象辆憔,然后過濾掉符合要求的對象撇眯,也就是要刪除的對象
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"number = %d",obj.number];
        request.predicate = predicate;
        
        // 通過執(zhí)行獲取操作,找到要刪除的對象即可
        NSError *error = nil;
        NSArray<CPStudent *> *students = [self.context executeFetchRequest:request error:&error];
        
        // 開始真正操作虱咧,一一遍歷叛本,遍歷符合刪除要求的對象數(shù)組,執(zhí)行刪除操作
        [students enumerateObjectsUsingBlock:^(CPStudent *obj, NSUInteger idx, BOOL *stop) {
            [self.context deleteObject:obj];
        }];
        
        // 錯誤處理
        if (error) {
            NSLog(@"刪除失敗");
        } else {
            NSLog(@"刪除成功");
        }
    }];
    
    // 最后保存數(shù)據(jù)彤钟,保存上下文。
    if (self.context.hasChanges) {
        [self.context save:nil];
    }
}

- (void)modify:(NSArray *)modifyStudents {
    // 獲取數(shù)據(jù)的請求對象跷叉,指明對實體進行刪除操作
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"CPStudent"];
    [modifyStudents enumerateObjectsUsingBlock:^(CPStudent *obj, NSUInteger idx, BOOL *stop) {
        // 通過創(chuàng)建謂詞對象逸雹,然后過濾掉符合要求的對象,也就是要刪除的對象
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"number = %d",obj.number];
        request.predicate = predicate;
        
        // 通過執(zhí)行獲取操作云挟,找到要刪除的對象即可
        NSError *error = nil;
        NSArray<CPStudent *> *students = [self.context executeFetchRequest:request error:&error];
        
        // 開始真正操作梆砸,一一遍歷,遍歷符合刪除要求的對象數(shù)組园欣,執(zhí)行刪除操作
        [students enumerateObjectsUsingBlock:^(CPStudent *obj, NSUInteger idx, BOOL *stop) {
            obj.age += 1;
            obj.sex = [obj.sex isEqualToString:@"男"] ? @"女" : @"男";
        }];
        
        // 錯誤處理
        if (error) {
            NSLog(@"改失敗");
        } else {
            NSLog(@"改成功");
        }
    }];
    
    // 最后保存數(shù)據(jù)帖世,保存上下文。
    if (self.context.hasChanges) {
        [self.context save:nil];
    }
}

- (NSArray<CPStudent *> *)fetchTapStudentData {
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"CPStudent"];
    
    // 執(zhí)行獲取操作沸枯,獲取所有Student托管對象
    NSError *error = nil;
    NSArray<CPStudent *> *students = [self.context executeFetchRequest:request error:&error];
    
    if (error) {
        NSLog(@"失敗");
    } else {
        NSLog(@"查找數(shù)據(jù)成功");
    }
    
    return students;
}

數(shù)據(jù)遷移

輕數(shù)據(jù)遷移

適用場景:

  • 添加日矫、刪除一個表或者屬性
  • 屬性值可空與不可空的改變
  • 重命名表或者屬性
  • 單一的一次遷移(如果出現(xiàn)多次版本遷移要一起做赂弓,就要進行逐步遷移,不能用輕數(shù)據(jù)遷移)
//請求自動輕量級遷移
             NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                                         [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                                         [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
                                         nil];
             NSError *error = nil;
            
            [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:newDataPath] options:options error:nil];

自定義數(shù)據(jù)遷移

創(chuàng)建MappingModel在指定映射哪轿。使用NSEntityMigrationPolicy類來指定遷移策略盈魁。

  1. 使用NSPersistentStoreCoordinator持久化調(diào)度器來獲取當(dāng)前版本model
  2. 使用NSManagedObjectModel獲取最新model
  3. 對本版本,漸進式遷移窃诉。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末杨耙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子飘痛,更是在濱河造成了極大的恐慌珊膜,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宣脉,死亡現(xiàn)場離奇詭異车柠,居然都是意外死亡,警方通過查閱死者的電腦和手機脖旱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門堪遂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人萌庆,你說我怎么就攤上這事溶褪。” “怎么了践险?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵猿妈,是天一觀的道長。 經(jīng)常有香客問我巍虫,道長彭则,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任占遥,我火速辦了婚禮俯抖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瓦胎。我一直安慰自己芬萍,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布搔啊。 她就那樣靜靜地躺著柬祠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪负芋。 梳的紋絲不亂的頭發(fā)上漫蛔,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天,我揣著相機與錄音,去河邊找鬼莽龟。 笑死蠕嫁,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的轧房。 我是一名探鬼主播拌阴,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼奶镶!你這毒婦竟也來了迟赃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤厂镇,失蹤者是張志新(化名)和其女友劉穎纤壁,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捺信,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡酌媒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了迄靠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秒咨。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖掌挚,靈堂內(nèi)的尸體忽然破棺而出雨席,到底是詐尸還是另有隱情,我是刑警寧澤吠式,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布陡厘,位于F島的核電站,受9級特大地震影響特占,放射性物質(zhì)發(fā)生泄漏糙置。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一是目、第九天 我趴在偏房一處隱蔽的房頂上張望谤饭。 院中可真熱鬧,春花似錦懊纳、人聲如沸网持。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至萍倡,卻和暖如春身弊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工阱佛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留帖汞,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓凑术,卻偏偏與公主長得像翩蘸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子淮逊,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

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