iOS学习笔记18-CoreData你懂的
一、CoreData介绍
CoreData是iOS5之后新出来的的一个框架, 是对SQLite进行一层封装升级后的一种数据持久化方式。
它提供了对象<-->关系映射的功能,即能够将OC对象转化为数据存储到SQLite数据库文件中,同时也能将数据库中的数据还原成OC对象。相较于SQLite,我们使用CoreData就不需要再编写任何SQL语句,再也不去纠结SQL语句怎么写了O(∩_∩)O哈~。
二、CoreData核心结构图
先来张官方的图:

PersistentObjectStore:存储持久对象的数据库(例如SQLite,注意CoreData也支持其他类型的数据存储,例如xml、二进制数据等)。ManagedObjectModel:对象模型,对应Xcode中创建的模型文件。PersistentStoreCoordinator:对象模型和实体类之间的转换协调器,用于管理不同存储对象的上下文。ManagedObjectContext:对象管理上下文,负责实体对象和数据库之间的交互。
说了这么多,可能你还是懵逼的,下面是我的理解图:

最底层的就是PersistentObjectStore,也就是我们实际存储数据的结构;
图中的模型就是ManagedObjectModel,就是数据转化为对象的模板;
以SQLite数据库为例:
- 读取数据库的数据时,数据库数据先进入数据解析器,根据对应的模板,生成对应的关联对象。
- 向数据库插入数据时,对象管理器先根据实体描述创建一个空对象,对该对象进行初始化,然后经过数据解析器,根据对应的模板,转化为数据库的数据,插入数据库中。
- 更新数据库数据时,对象管理器需要先读取数据库的数据,拿到相互关联的对象,对该对象进行修改,修改的数据通过数据解析器,转化为数据库的更新数据,对数据库更新。
这些还是要在使用中进行加深理解
三、CoreData使用
1. 添加框架
- 添加
CoreData.framework #import导入头文件<CoreData/CoreData.h>
2. 数据模板和对象模型
看上面的图就知道,我们需要首先创建一个数据模板,即ManagedObjectModel
下面是创建数据模板的步骤【是图形化操作,所以都是图片】:





点击Next,会进入一个数据模板文件的选择打钩,再点Next,会进入一个实体的选择打钩,选完点Next就会自动生成对象模型文件。

- 所有的实体类型都继承于
NSManagedObject,每个NSManagedObject对象对应着数据库中一条记录。 - 集合属性(例如数组)会自动生成访问此属性的分类方法。
- 使用
@dynamic代表具体属性实现,具体实现细节不需要开发人员关心。
3. 创建对象管理上下文
创建对象管理上下文ManagedObjectContext可以细分为:
- 加载模型文件
- 指定数据存储路径
- 创建对应数据类型的存储
- 创建管理对象上下方并指定存储
下面是实例代码:
- (NSManagedObjectContext *)createDbContext{
//打开模型文件,参数为nil则打开包中所有模型文件并合并成一个
NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
//创建数据解析器
NSPersistentStoreCoordinator *storeCoordinator =
[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
//创建数据库保存路径
NSString *dir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject;
NSString *path = [dir stringByAppendingPathComponent:@"myDatabase.db"];
NSURL *url = [NSURL fileURLWithPath:path];
//添加SQLite持久存储到解析器
NSError *error;
[storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:url
options:nil
error:&error];
NSManagedObjectContext *context = nil;
if( !error ){
//创建对象管理上下文,并设置数据解析器
context = [[NSManagedObjectContext alloc] init];
context.persistentStoreCoordinator = storeCoordinator;
NSLog(@"数据库打开成功!");
}else{
NSLog(@"数据库打开失败!错误:%@",error.localizedDescription);
}
return context;
}
4. 插入数据
插入数据我们需要创建一个实体对象,并把这个对象关联上对象管理器,我们创建实体对象需要使用到NSEntityDescription(实体描述类)的类方法
下面是实现代码:
- (void)addClassTest
{
//添加一个对象
Classes *classes = [NSEntityDescription insertNewObjectForEntityForName:@"Classes"
inManagedObjectContext:self.context];
classes.c_id = 301;
classes.c_name = @"高三(1)班";
NSError *error;
//保存上下文,这里需要注意,增、删、改操作完最后必须调用管理对象上下文的保存方法,否则操作不会执行。
if (![self.context save:&error]) {
NSLog(@"添加过程中发生错误,错误信息:%@!",error.localizedDescription);
}
}
5. 删除数据
删除数据,只需要删除关联的对象就行了:
- (void)removeClasses:(Classes *classes){
[self.context deleteObject:classes];
NSError *error;
if (![self.context save:&error]) {
NSLog(@"删除过程中发生错误,错误信息:%@!",error.localizedDescription);
}
}
6. 查询数据
查询数据需要处理查询结果,要用到两个类:
NSFetchRequest:获取数据的请求NSPredicate:请求的谓词,也就是获取数据的要求
1. 查询一个对象只有唯一一个关联对象的情况
例如查找用户名为“Binger”的微博(一个微博只能属于一个用户),通过keypath查询:
- (NSArray *)getStatusByUserName:(NSString *)name{
//创建查询请求
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Status"];
//创建谓词,设置获取数据的条件
request.predicate = [NSPredicate predicateWithFormat:@"user.name=%@",name];
//执行对象管理上下文的查询方法
NSArray *array = [self.context executeFetchRequest:request error:nil];
return array;
}
2. 查询一个对象有多个关联对象的情况
例如查找发送微博内容中包含“Watch”并且用户昵称为“小娜”的用户(一个用户有多条微博)
- (NSArray *)getUsersByStatusText:(NSString *)text screenName:(NSString *)screenName{
//创建查询请求
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Status"];
//设置查询条件
request.predicate = [NSPredicate predicateWithFormat:@"text LIKE '*Watch*'",text];
//获取查询结果
NSArray *statuses = [self.context executeFetchRequest:request error:nil];
//下面是用谓词对上面的结果进行过滤
NSPredicate *userPredicate = [NSPredicate predicateWithFormat:@"user.screenName=%@",screenName];
//对查询结果再进行过滤
NSArray *users = [statuses filteredArrayUsingPredicate:userPredicate];
return users;
}
7. 修改数据
只需要拿到对应的关联对象,直接修改,然后保存
- (void)modifyClasses:(Classes *)classes
{
classes.name = @"吊炸天毕业(1)班";
NSError *error;
if (![self.context save:&error]) {
NSLog(@"修改过程中发生错误,错误信息:%@",error.localizedDescription);
}
}
四、CoreData调试
事实上在Xcode中是支持CoreData调试的,具体操作:
Product->SchemeScheme->Edit SchemeEdit Scheme->RunRun->Arguments
依次添加两个参数(注意参数顺序不能错):

然后在运行程序过程中,如果操作了数据库,就会将SQL语句打印在输出面板。
注意:如果模型发生了变化,此时可以重新生成实体类文件,但是所生成的数据库并不会自动更新,这时需要考虑重新生成数据库并迁移原有的数据。
这一节感觉写的不好,很多东西没法写太细,很多概念也不好理解,希望大家体谅,有建议可以在下方的评论区提出,O(∩_∩)O哈!
iOS学习笔记18-CoreData你懂的的更多相关文章
- iOS学习笔记-CoreData
简介 CoreData提供了对象关系映射(ORM)功能,从效果上说就是创建了一个"虚拟对象数据库",也可以把它看作一个综合的数据库管理库. NSManagedObjectConte ...
- iOS学习笔记-精华整理
iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始 ...
- golang学习笔记18 用go语言编写移动端sdk和app开发gomobile
golang学习笔记18 用go语言编写移动端sdk和app开发gomobile gomobile的使用-用go语言编写移动端sdk和app开发https://blog.csdn.net/u01249 ...
- IOS学习笔记48--一些常见的IOS知识点+面试题
IOS学习笔记48--一些常见的IOS知识点+面试题 1.堆和栈什么区别? 答:管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制:对于堆来说,释放工作由程序员控制,容易产生memor ...
- iOS学习笔记17-FMDB
上一节我已经介绍了SQLite的简单使用,不了解的可以提前去看一下iOS学习笔记16-数据库SQLite,这节我们来讲下FMDB. 一.FMDB介绍 FMDB是一种第三方的开源库,FMDB就是对SQL ...
- iOS学习笔记17-FMDB你好!
上一节我已经介绍了SQLite的简单使用,不了解的可以提前去看一下iOS学习笔记16-数据库SQLite,这节我们来讲下FMDB. 一.FMDB介绍 FMDB是一种第三方的开源库,FMDB就是对SQL ...
- iOS学习笔记——AutoLayout的约束
iOS学习笔记——AutoLayout约束 之前在开发iOS app时一直以为苹果的布局是绝对布局,在IB中拖拉控件运行或者直接使用代码去调整控件都会发上一些不尽人意的结果,后来发现iOS在引入了Au ...
- IOS学习笔记25—HTTP操作之ASIHTTPRequest
IOS学习笔记25—HTTP操作之ASIHTTPRequest 分类: iOS2012-08-12 10:04 7734人阅读 评论(3) 收藏 举报 iosios5网络wrapper框架新浪微博 A ...
- IOS学习笔记之关键词@dynamic
IOS学习笔记之关键词@dynamic @dynamic这个关键词,通常是用不到的. 它与@synthesize的区别在于: 使用@synthesize编译器会确实的产生getter和setter方法 ...
- iOS学习笔记10-UIView动画
上次学习了iOS学习笔记09-核心动画CoreAnimation,这次继续学习动画,上次使用的CoreAnimation很多人感觉使用起来很繁琐,有没有更加方便的动画效果实现呢?答案是有的,那就是UI ...
随机推荐
- poj3463 Sightseeing——次短路计数
题目:http://poj.org/problem?id=3463 次短路计数问题,在更新最短路的同时分类成比最短路短.长于最短路而短于次短路.比次短路长三种情况讨论一下,更新次短路: 然而其实不必被 ...
- bzoj1106
模拟+树状数组 先开始以为是先删距离最小的,这样可以减小上下的距离,然后觉得很难写,看码长很短,就看了题解,结果很奥妙 我们只考虑两种元素,就是如果像-a-b-a-b-这样的肯定得交换,如果像-a-b ...
- PCB SQL SERVER 发送邮件(异步改同步)
采用SQL SERVER发送邮件是队列方式(异步)发送邮件,所以在我们执行发送邮件后,无法立即获取到邮件是否发送成功了,而在PCB行业实际应用中是需要立即获取发送邮件是否成功的状态来决定下一步逻辑该如 ...
- activiti安装-------安装插件
对上面的放大
- javaEE框架获取和传参要使用的类和接口
1:spring 2:struts2获取前台数据(action中获取) //4修改用户密码. public String updateUserPassword() throws Exception{ ...
- python3+request接口自动化框架
首次书写博客,记录下写的自动化接口框架,框架比较简单,哈哈哈,算是记录下历程把!~~~ 一.本次框架由python3.6 书写 1.准备代码环境,下载python3.6 下载地址:https:/ ...
- Activity启动模式(GIF 动态演示)
本文首发在我的个人微信公众号:Android开发圈 引言 关于Activity的启动模式是面试高频问题,在平时开发中,作用也不小,所以还是很有必要搞懂这一块的知识.其实之前也有写过这个主题的文章,但是 ...
- [LeetCode]152. Maximum Product Subarray
This a task that asks u to compute the maximum product from a continue subarray. However, you need t ...
- 研磨JavaScript系列(五):奇妙的对象
在JavaScript中,只有object和function两种东西有对象化的能力.我们先来说说函数的对象化能力. 任何一个函数都可以为其动态地添加或去除属性,这些属性可以是简单类型,可以是对象,也可 ...
- 给定的逗号分隔的数字字符串转换为Table
--将给定的逗号分隔的数字字符串转换为Table CREATE FUNCTION [dbo].[fu_Split](@strString nvarchar(4000)) RETURNS @Result ...