iOS开发数据持久化之-CoreData

CoreData使用了面向对象的方式来操作数据,负责在数据库中存储数据.它的底层就是使用类似于SQL的技术来实现的.CoreData提供了一种简便的对象持久化管理方式,让我们可以不关心数据的存储,只需关心对象的增加,删除,更改,读写就好了.

CoreData介绍

  1. CoreData是苹果公司封装的数据持久化框架,在iOS3.0中开始开放.
  2. 它允许用户按照实体-属性-值模型组织数据,并以二级制,XML或者sqlite数据文件的格式进行持久化

优点

  1. 它是苹果公司原生态的产品.
  2. 它可以节省代码量,大概是30%~70%
  3. 它支持可视化建模
  4. CoreData支持数据库版本升级

构成

我们在创建工程的时候,勾选Use Core Data选项,系统就会在AppDelegate自动帮我们生成包含CoreData的属性和方法.并且生成一个test.xcdatamodeld的文件.

Use Core Data

在AppDelegate文件中

APPDelegate.h

上面图片是系统自动帮我们生成的属性和方法代码.它们的作用分别是:

三个属性:

1.managedObjectContext,是被管理的数据上下文.它被用来操作实际的内容,进行插入,查询,删除数据.
2.managedObjectModel,它是一个被管理的数据模型.可以简单的理解为可视化建模文件,我们在可视化建模中是Entity自动生成Model,就是这个对象,方便让文件存储助理来进行管理.
3.persistentStoreCoordinator,这是一个持久化的存储助理.它是CoreData的核心,他负责连接所有的模块,包括真实的存储文件.

两个方法:
1.saveContext,它的作用就是将我们在内存中的数据进行持久化.
2.applicationDocumentsDirectory,这个方法是用来获取真实文件的路径的.

使用CoreData

这是使用一个简单的例子,对CoreData的增,删,改,查的使用进行说明.

创建Entity

我们使用CoreData实现数据在tableView上的展示(查),添加(增),删除(删),点击更改(改).

UI界面

在storyboard中创建一个UITableViewController,把它放在NavgationController中,设置一个右按钮.为其关联方法,并且指定其为 initial View Controller.创建类文件,并进行关联,设置cell的样式为Subtitle.
在这里不详细赘述,如果想要了解可以移步[http://www.jianshu.com/p/872b84d982ae]

UI界面搭建,简单演示

创建文件

选中.xcdatamodeld文件,按照上面的步骤创建一个Person实例,点击任务栏的Editor按钮,选择下图红框中的选项创建文件.

创建Person文件

因为我们创建工程的时候,系统已经为我们在AppDelegate生成了一些属性和方法.我们只需要在tableView中引入APPDelegate的头文件就好了.

代码
属性

声明两个属性,一个是上下文对象,我们使用它来处理所有关于存储的相关请求.另外一个就是数据源啦,用来在tableView上展示的数据.

既然声明了属性,我们就需要在为他们初始化,我们在ViewDidLoad方法中为其初始化,因为我们的managedObjectContext是来自与AppDelegate,所以选择下面的初始化方法.

    // 进行数据初始化
    AppDelegate *dele = [UIApplication sharedApplication].delegate;
    self.myContext = dele.managedObjectContext;
    
    self.allData = [NSMutableArray array];
    
    // 通过CoreData读取本地所有的数据
    [self getAllDataFromCoreData];

点击添加按钮添加数据

// 添加数据
- (IBAction)addAction:(UIBarButtonItem *)sender {
    
    // 创建student对象
    // 创建一个实体描述对象
    NSEntityDescription *stuDis = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:self.myContext];
    Student *stu = [[Student alloc]initWithEntity:stuDis insertIntoManagedObjectContext:self.myContext];
    // 给属性赋值
    stu.name = @"张三";
    stu.age = arc4random() % 73 + 1;
    
    // 更新数据源
    [self.allData addObject:stu];
    // 修改界面
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.allData.count - 1 inSection:0];
    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
    // 将数据保存到文件中进行持久化
    NSError *error = nil;
    [self.myContext save:&error];
    
    if (nil != error) {
        NSLog(@"数据库持久化,存在问题");
    }
    [((AppDelegate *)[UIApplication sharedApplication].delegate) saveContext];
}

从数据库查询数据

- (void)getAllDataFromCoreData {
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:self.myContext];
    [fetchRequest setEntity:entity];
    // 排序条件
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"age"
                                                                   ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]];
    
    NSError *error = nil;
    NSArray *fetchedObjects = [self.myContext executeFetchRequest:fetchRequest error:&error];
    if (fetchedObjects == nil) {
        NSLog(@"两手空空,你让我如何盆满钵满");
    }
    // 将查询到的数据添加到数据源
    [self.allData addObjectsFromArray:fetchedObjects];
    // 从新加载tableView
    [self.tableView reloadData];
}

点击cell改变数据

// 点击cell的响应事件
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    // 先查询
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:self.myContext];
    [fetchRequest setEntity:entity];
    // Specify how the fetched objects should be sorted
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"age"
                                                                   ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]];
    
    NSError *error = nil;
    NSArray *fetchedObjects = [self.myContext executeFetchRequest:fetchRequest error:&error];
    Student *stu = self.allData[indexPath.row];
    stu.name = @"尼古拉斯-赵四";
    stu.age = 15;
    // 更新数据源
    [self.allData removeAllObjects];
    [self.allData addObjectsFromArray:fetchedObjects];
    // 刷新UI
    [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
    // 将修改本地持久化
    [self.myContext save:nil];
}

设置编辑时间 右滑删除

// 当点击tableViewCell的删除按钮的时候回调用(提交编辑请求的时候)
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

        // 获取当前cell代表的数据
        Student *stu = self.allData[indexPath.row];
        // 更新数据源
        [self.allData removeObject:stu];
        // 更新UI
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
        // 将临时数据库里进行删除并进行本地持久化
        [self.myContext deleteObject:stu];
        [self.myContext save:nil];
      
}

其他的方法,设置分区数,行数,以及cell

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return self.allData.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"main_cell" forIndexPath:indexPath];
    
    Student *stu = self.allData[indexPath.row];
    
    cell.textLabel.text = stu.name;
    cell.detailTextLabel.text = [NSString stringWithFormat:@"%d",stu.age];
    
    return cell;
}

最后的效果

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

推荐阅读更多精彩内容

  • 1.CoreData 1.1 CoreData概述 1)Core data 是数据持久存储的最佳方式 2)Core...
    微春风阅读 3,806评论 0 10
  • 在程序开发中,数据层永远是程序的核心结构之一。我们将现实事物进行抽象,使之变成一个个数据。对这些数据的加工处理是代...
    帅不过oneS阅读 593评论 0 1
  • 在程序开发中,数据层永远是程序的核心结构之一。我们将现实事物进行抽象,使之变成一个个数据。对这些数据的加工处理是代...
    sindri的小巢阅读 16,830评论 13 85
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 说到吃Pizza,你的脑海中是否只会浮现Pizzahut必胜客的身影?如果是这样,那今天的这期餐厅推荐将会让你在P...
    港漂圈豆豆阅读 523评论 1 4