【iOS】CoreData详解

什么是CoreData

  • CoreData 不是一个数据库但是可以使用数据库来存储数据,也可以使用其他方式,比如:数据库文件,XML,二进制文件,内存等。CoreData 提供了 对象-关系映射(ORM) 功能。能够实现数据库数据和 OC 对象的相互转换,在这个转换过程中我们不需要编写任何 SQL 语句。

  • 可以简单的理解为Cocoa对SQLite的一层封装

为什么要使用CoreData

  • 极大的减少Model层的代码量

  • 优化了使用SQLite时候的性能

  • 提供了可视化设计

CoreData框架

CoreData

  • .xcdatamodeld 文件:定义了数据库数据和 OC 对象转换的映射关系,编译后为 .momod 文件

  • NSManagedObjectModel:负责读取解析 .momod 文件

  • NSPersistentStoreCoordinator:通过解析结果去实现数据库和 OC 对象之间的相互转换,主要是操作数据库的,我们一般用不上,由系统处理

  • NSManagedObjectContext:等同于一个容器,用来存储从数据库中转换出来的所有的 OC 对象。我们的增删改查操作直接对这个类使用来获得或者修改需要的 OC 对象,它能够调用 NSPersistentStoreCoordinator 类实现对数据库的同步

  • NSManagedObject:数据库中的数据转换而来的OC对象

*注:
1. 一旦数据创建完毕,就不能再修改.xcdatamodeld文件,如果有修改,必须删除数据库重新创建,否则打开数据库已定会失败。 去沙盒路径下把创建的数据库删除即可
2. 不能使用alloc init来创建对象


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

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow * window;

/**
  * 上下文  容器  
  * 存放的是 所有从数据库中取出的转换成OC对象
  */
@property (readonly, strong, nonatomic) NSManagedObjectContext * managedObjectContext;

/* 读取解析 .momd文件中的内容 */
@property (readonly, strong, nonatomic) NSManagedObjectModel * managedObjectModel;

/* 连接的类,处理数据库数据和OC数据底层的相互转换 */
@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);

    
    //插入一条数据 (往People表中插入一条数据)
    //NSEntityDescription 实体类
    //EntityForName 实体名称(表名)
    People * p = [NSEntityDescription insertNewObjectForEntityForName:@"People" inManagedObjectContext:self.managedObjectContext];
    //赋值
    p.name = @"李四";
    p.age = @(25);
    p.phone = @"13667895678";
    //同步操作  把context中的数据同步到数据库中
    [self saveContext];
    
    
    
    // 查询数据
    // 创建查询请求
    NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"People"];
    // Context 执行请求(执行查询操作) 数组中存放的是oc类的对象(People类的对象)
    NSArray * array = [self.managedObjectContext executeFetchRequest:request error:nil];
    for (People *people in array)
    {
       NSLog(@"%@",people.name);
    }
    
    
    //查询特定条件数据  (年龄>20)
    NSFetchRequest * request1 = [NSFetchRequest fetchRequestWithEntityName:@"People"];
    //使用谓词指定查询的判定条件
    NSPredicate * predicate = [NSPredicate predicateWithFormat:@"SELF.age > 20"];
    //关联判定条件
    [request1 setPredicate:predicate];
    //执行查询操作
    NSArray * array2 = [self.managedObjectContext executeFetchRequest:request1 error:nil];
    for (People * people in array2)
    {
        NSLog(@"%@",people.age);
    }
    
    

    //更改数据
    //获取出要修改的数据
    People * people2 = [array lastObject];
    //修改属性
    people2.name = @"123";
    people2.age  = @(30);
    //同步数据
    [self saveContext];
    


    //删除数据
    People * people3 = [array lastObject];
    [self.managedObjectContext deleteObject:people3];
    //同步数据
    [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"];
    
    //把文件的内容读取到managedObjectModel中
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    
    return _managedObjectModel;
}

//Coordinator 调度者负责数据库的操作 创建数据库 打开数据 增删改查数据
-(NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) return _persistentStoreCoordinator;

    //根据model创建了persistentStoreCoordinator
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    
    // 设置数据库存放的路径
    NSURL * storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreData_Class.sqlite"];
    
    NSError * error = nil;
    
    //如果没有得到数据库,程序崩溃
    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;
    }
    
    //创建context对象
    _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    
    //让context和coordinator关联   context可以对数据进行增删改查功能
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    
    return _managedObjectContext;
}

#pragma mark - Core Data Saving support

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

        // hasChanges 判断数据是否更改
        // sava 同步数据库中的数据
        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    描述对应@synthesize和@synamic两个关键字
 * @synthesize  会生成属性的setter,getter方法
 * @dynamic     不生成属性的setter,getter方法
 * 两个都没有写,默认是@synthesize
 */

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

@end

参考文献

微信公共号:iapp666666
GitHub:点此前往

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容