【iOS】CoreData詳解

什么是CoreData

  • CoreData 不是一個數(shù)據(jù)庫但是可以使用數(shù)據(jù)庫來存儲數(shù)據(jù)肴盏,也可以使用其他方式俊犯,比如:數(shù)據(jù)庫文件,XML贤惯,二進制文件洼专,內(nèi)存等。CoreData 提供了 對象-關(guān)系映射(ORM) 功能孵构。能夠?qū)崿F(xiàn)數(shù)據(jù)庫數(shù)據(jù)和 OC 對象的相互轉(zhuǎn)換屁商,在這個轉(zhuǎn)換過程中我們不需要編寫任何 SQL 語句。

  • 可以簡單的理解為Cocoa對SQLite的一層封裝

為什么要使用CoreData

  • 極大的減少Model層的代碼量

  • 優(yōu)化了使用SQLite時候的性能

  • 提供了可視化設(shè)計

CoreData框架

CoreData

  • .xcdatamodeld 文件:定義了數(shù)據(jù)庫數(shù)據(jù)和 OC 對象轉(zhuǎn)換的映射關(guān)系颈墅,編譯后為 .momod 文件

  • NSManagedObjectModel:負責讀取解析 .momod 文件

  • NSPersistentStoreCoordinator:通過解析結(jié)果去實現(xiàn)數(shù)據(jù)庫和 OC 對象之間的相互轉(zhuǎn)換蜡镶,主要是操作數(shù)據(jù)庫的,我們一般用不上恤筛,由系統(tǒng)處理

  • NSManagedObjectContext:等同于一個容器官还,用來存儲從數(shù)據(jù)庫中轉(zhuǎn)換出來的所有的 OC 對象。我們的增刪改查操作直接對這個類使用來獲得或者修改需要的 OC 對象毒坛,它能夠調(diào)用 NSPersistentStoreCoordinator 類實現(xiàn)對數(shù)據(jù)庫的同步

  • NSManagedObject:數(shù)據(jù)庫中的數(shù)據(jù)轉(zhuǎn)換而來的OC對象

*注:
1. 一旦數(shù)據(jù)創(chuàng)建完畢望伦,就不能再修改.xcdatamodeld文件林说,如果有修改,必須刪除數(shù)據(jù)庫重新創(chuàng)建屯伞,否則打開數(shù)據(jù)庫已定會失敗腿箩。 去沙盒路徑下把創(chuàng)建的數(shù)據(jù)庫刪除即可
2. 不能使用alloc init來創(chuàng)建對象


AppDelegate.h
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow * window;

/**
  * 上下文  容器  
  * 存放的是 所有從數(shù)據(jù)庫中取出的轉(zhuǎn)換成OC對象
  */
@property (readonly, strong, nonatomic) NSManagedObjectContext * managedObjectContext;

/* 讀取解析 .momd文件中的內(nèi)容 */
@property (readonly, strong, nonatomic) NSManagedObjectModel * managedObjectModel;

/* 連接的類,處理數(shù)據(jù)庫數(shù)據(jù)和OC數(shù)據(jù)底層的相互轉(zhuǎn)換 */
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator * persistentStoreCoordinator;

/* 保存 */
-(void)saveContext;

/* 獲取沙盒路徑 */
-(NSURL *)applicationDocumentsDirectory;

@end
AppDelegate.m
#import "AppDelegate.h"
#import "People.h"

@interface AppDelegate ()
@end

@implementation AppDelegate

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSLog(@"沙盒路徑路徑:%@",[self applicationDocumentsDirectory].absoluteString);
    
    NSLog(@"%@",self.managedObjectContext);

    
    //插入一條數(shù)據(jù) (往People表中插入一條數(shù)據(jù))
    //NSEntityDescription 實體類
    //EntityForName 實體名稱(表名)
    People * p = [NSEntityDescription insertNewObjectForEntityForName:@"People" inManagedObjectContext:self.managedObjectContext];
    //賦值
    p.name = @"李四";
    p.age = @(25);
    p.phone = @"13667895678";
    //同步操作  把context中的數(shù)據(jù)同步到數(shù)據(jù)庫中
    [self saveContext];
    
    
    
    // 查詢數(shù)據(jù)
    // 創(chuàng)建查詢請求
    NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"People"];
    // Context 執(zhí)行請求(執(zhí)行查詢操作) 數(shù)組中存放的是oc類的對象(People類的對象)
    NSArray * array = [self.managedObjectContext executeFetchRequest:request error:nil];
    for (People *people in array)
    {
       NSLog(@"%@",people.name);
    }
    
    
    //查詢特定條件數(shù)據(jù)  (年齡>20)
    NSFetchRequest * request1 = [NSFetchRequest fetchRequestWithEntityName:@"People"];
    //使用謂詞指定查詢的判定條件
    NSPredicate * predicate = [NSPredicate predicateWithFormat:@"SELF.age > 20"];
    //關(guān)聯(lián)判定條件
    [request1 setPredicate:predicate];
    //執(zhí)行查詢操作
    NSArray * array2 = [self.managedObjectContext executeFetchRequest:request1 error:nil];
    for (People * people in array2)
    {
        NSLog(@"%@",people.age);
    }
    
    

    //更改數(shù)據(jù)
    //獲取出要修改的數(shù)據(jù)
    People * people2 = [array lastObject];
    //修改屬性
    people2.name = @"123";
    people2.age  = @(30);
    //同步數(shù)據(jù)
    [self saveContext];
    


    //刪除數(shù)據(jù)
    People * people3 = [array lastObject];
    [self.managedObjectContext deleteObject:people3];
    //同步數(shù)據(jù)
    [self saveContext];
    
    return YES;
}

//點擊HOME鍵程序直接退出
-(void)applicationWillTerminate:(UIApplication *)application
{
    [self saveContext];
}

#pragma mark - Core Data stack

@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

-(NSURL *)applicationDocumentsDirectory
{
    //獲取沙盒路徑下documents文件夾的路徑 NSURL   (類似于search)
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

//managedObjectModel 屬性的getter方法
-(NSManagedObjectModel *)managedObjectModel
{
    if (_managedObjectModel != nil) return _managedObjectModel;

    //.xcdatamodeld文件 編譯之后變成.momd文件  (.mom文件)
    NSURL * modelURL = [[NSBundle mainBundle] URLForResource:@"CoreData_Class" withExtension:@"momd"];
    
    //把文件的內(nèi)容讀取到managedObjectModel中
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    
    return _managedObjectModel;
}

//Coordinator 調(diào)度者負責數(shù)據(jù)庫的操作 創(chuàng)建數(shù)據(jù)庫 打開數(shù)據(jù) 增刪改查數(shù)據(jù)
-(NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) return _persistentStoreCoordinator;

    //根據(jù)model創(chuàng)建了persistentStoreCoordinator
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    
    // 設(shè)置數(shù)據(jù)庫存放的路徑
    NSURL * storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreData_Class.sqlite"];
    
    NSError * error = nil;
    
    //如果沒有得到數(shù)據(jù)庫劣摇,程序崩潰
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
    {
        NSLog(@"錯誤信息: %@, %@", error, [error userInfo]);
        abort(); //崩潰
    }
    
    return _persistentStoreCoordinator;
}

//容器類 存放OC的對象
-(NSManagedObjectContext *)managedObjectContext
{
    if (_managedObjectContext != nil)  return _managedObjectContext;
    
    NSPersistentStoreCoordinator * coordinator = [self persistentStoreCoordinator];
    if (!coordinator)
    {
        return nil;
    }
    
    //創(chuàng)建context對象
    _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    
    //讓context和coordinator關(guān)聯(lián)   context可以對數(shù)據(jù)進行增刪改查功能
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    
    return _managedObjectContext;
}

#pragma mark - Core Data Saving support

-(void)saveContext
{
    NSManagedObjectContext * managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil)
    {
        NSError * error = nil;

        // hasChanges 判斷數(shù)據(jù)是否更改
        // sava 同步數(shù)據(jù)庫中的數(shù)據(jù)
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error])
        {
            NSLog(@"錯誤信息: %@, %@", error, [error userInfo]);
            abort();
        }
    }
}

@end
People.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@interface People : NSManagedObject

@property (nonatomic, retain) NSNumber * age;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * phone;

@end
People.m
#import "People.h"

@implementation People

/**
 * @property    描述對應(yīng)@synthesize和@synamic兩個關(guān)鍵字
 * @synthesize  會生成屬性的setter珠移,getter方法
 * @dynamic     不生成屬性的setter,getter方法
 * 兩個都沒有寫饵撑,默認是@synthesize
 */

@dynamic age;
@dynamic name;
@dynamic phone;

@end

參考文獻

微信公共號:iapp666666
GitHub:點此前往

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末剑梳,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子滑潘,更是在濱河造成了極大的恐慌垢乙,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件语卤,死亡現(xiàn)場離奇詭異追逮,居然都是意外死亡,警方通過查閱死者的電腦和手機粹舵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進店門钮孵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人眼滤,你說我怎么就攤上這事巴席。” “怎么了诅需?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵漾唉,是天一觀的道長。 經(jīng)常有香客問我堰塌,道長赵刑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任场刑,我火速辦了婚禮般此,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘牵现。我一直安慰自己铐懊,他們只是感情好,可當我...
    茶點故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布瞎疼。 她就那樣靜靜地躺著科乎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪丑慎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天,我揣著相機與錄音竿裂,去河邊找鬼玉吁。 笑死,一個胖子當著我的面吹牛腻异,可吹牛的內(nèi)容都是我干的进副。 我是一名探鬼主播,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼悔常,長吁一口氣:“原來是場噩夢啊……” “哼影斑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起机打,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤矫户,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后残邀,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體皆辽,經(jīng)...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年芥挣,在試婚紗的時候發(fā)現(xiàn)自己被綠了驱闷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,664評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡空免,死狀恐怖空另,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蹋砚,我是刑警寧澤扼菠,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站都弹,受9級特大地震影響娇豫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜畅厢,卻給世界環(huán)境...
    茶點故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一冯痢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧框杜,春花似錦浦楣、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至油狂,卻和暖如春历恐,著一層夾襖步出監(jiān)牢的瞬間寸癌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工弱贼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蒸苇,地道東北人。 一個月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓吮旅,卻偏偏與公主長得像溪烤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子庇勃,可洞房花燭夜當晚...
    茶點故事閱讀 43,554評論 2 349

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

  • 該文章屬于劉小壯原創(chuàng)檬嘀,轉(zhuǎn)載請注明:劉小壯[http://www.reibang.com/u/2de707c93d...
    劉小壯閱讀 19,761評論 17 149
  • iOS CoreData介紹和使用(以及一些注意事項) 最近花了一點時間整理了一下CoreData,對于經(jīng)常使用S...
    Pocket閱讀 22,816評論 34 92
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,131評論 30 470
  • 夜太黑 黑到看不見前方的路 所以我們才要成為 一顆即使孤獨也要燦爛的星辰 路太遠 遠得忘了出發(fā)時的驕傲 所以我們才...
    橫渡太平洋的魚閱讀 224評論 2 10
  • 每逢休息日,只要有詹姆斯的比賽直播再层,我都會守在屏幕前贸铜,不肯錯過哪怕一秒偶像的時間。 詹姆斯在比賽中無所不能聂受,控球蒿秦、...
    氧氣是個地鐵閱讀 247評論 0 0