iOS-Core Data 详解
使用Core Data 框架
Core Data框架本质就是一个ORM(对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,
用于实现面向对象编程语言里不同类型系统的数据之间的转换。)虽然Core Data
也允许把数据保存在内存中,或存储为非SQLite数据库的其他存储格式,但实际上绝大部分情况下,Core Data底层都采用SQLite数据库作为持久存储方式
Core Data简介
|
Core Data是一个纯粹的面向对象框架,可用于管理实体以及实体之间的关联关系的持久化—Core Data可以将实体保存到持久存储设备中,也可以在需要的时候将它们取出来. |
|
Core Data底层的持久化存储方式可以是SQLite数据库,也可以是XML文档,甚至可以直接以内存作为持久化存储设备(选择内存作为持久化存储设备,应用重启时,数据就会丢失.) |
|
Core Data的核心概念是实体.实体是由Core Data管理(简称被托管)的模型对象,它必须是NSManagedObject类或其子类的实例.实体与实体之间存在1-1\1-N\N-N的关联关系,整个应用的所有实体以及实体之间的关联关系被称为托管对象模型(NSManagedObjectModel). |
|
Core Data的核心对象是托管对象上下文(NSManagedObjectContext,有时也简称上下文),所有实体都处于托管对象上下文管理中,Core Data应用对实体所做的任何增\删\改\查操作必须通过托管对象上下文来完成. NSManagedObjectContext底层与持久化存储协调器衔接,持久化存储协调器则负责管理底层的存储形式(比如SQLite).
|
Core Data应用中的核心API有如下几个.
|
托管对象模型(NSManagedObjectModel): |
该对象负责管理整个应用的所有实体以及实体之间的关联关系.当开发者使用Xcode的图形界面设计了实体与实体的关联关系之后,需要使用该对象来加载,管理应用的托管对象模型. |
|
持久化存储协调器(NSPersistentStoreCoordinator): |
负责管理底层的存储文件,例如SQLite数据库等. |
|
托管对象上下文(NSManagedObjectContext): |
该对象是Core Data的核心对象,应用程序对实体所做的增\删\改\查操作都需要通过该对象来完成. |
|
实体描述(NSEntityDescription): |
该对象代表了关于某个实体的描述信息,从某种程度来说,该对象相当于实体的抽象. 实体描述定义了该实体的名字\实体的实现类,并用一个集合定义了该实体包含的所有属性
|
|
抓取请求(NSFetchRequest) |
该对象封装了查询实体的请求,包括程序需要查询哪些实体\查询条件\排序规则等
|
掌握了API之后,使用Core Data持久化操作的步骤大致如下.
|
1 |
创建NSManagedObjectModel对象来加载管理应用的托管对象模型 |
|
2 |
以NSManagedObjectModel对象为基础,根据实际需要创建NSPersistentStoreCoordinator对象,该对象确定Core Data底层数据的存储形式 |
|
3 |
以NSManagedObjectModel对象为基础,创建NSManagedObjectContext,该对象是Core Data进行持久化访问的核心对象 |
|
4 |
对于普通的增\删\改操作,需要分别先新建实体\删除实体\修改实体,然后调用NSManagedObjectContext对象的save:方法将这些修改保存到底层存储设备 |
|
5 |
如果要执行查询,则需要先创建NSFetchRequest对象,再调用NSManagedObjectContext的executeFetchRequest: error:方法执行查询,该方法返回所有匹配条件的实体组成的NSArray. |
初始化Core Data项目
iOS允许在创建iOS项目时勾选”Use Core Data”复选框,通过这种方式创建的iOS项目已经完成了所有Core Data必需资源的初始化.
“手动”初始化Core Data项目步骤如下
|
1 |
为该项目添加CoreData.framework框架.为了让项目显示更好的组织结构,将该框架拖入项目的Frameworks目录下 |
|
2 |
为该项目添加一个实体模型文件,单击Xcode主菜单的”File” →”New”→”File”菜单项,Xcode显示下图所示的对话框
|
|
3 |
初始化Core Data应用必需的核心API对象:NSManagedObjectModel\NSPersistentStoreCoordinator\NSManagedObjectContext. |
|
4 |
在AppDelegate.m文件中-(void)applicationWillTerminate:(UIApplication *)application方法---当应用将要被中断时,应用程序会自动回调 该方法,该方法中调用saveContext方法执行保存.如果不在该方法中执行保存,当应用被中断后,该应用可能进入后台,就有可能在后台被终止,这样就会导致该托管对象上下文中保存的数据丢失. |
设计实体模型
|
对模型可以添加如下3种对象 |
||
|
实体 |
这是实体模型最核心的对象,每个实体都必须是NSManagedObject类或其子类 |
|
|
抓取请求 |
NSFetchRequest对象,Xcode允许在图形界面上设计抓取请求对象,但实际上,通常都会在代码中创建NSFetchRequest对象 |
|
|
配置 |
一般无须自行添加配置对象,当开发者添加实体后,系统会自动添加默认的配置 |
|
|
每个实体可以添加如下的3种属性 |
||
|
属性(Attribute) |
该属性相当于实体对象的实例变量,用于记录该实体的状态. |
|
|
关联关系(Relationships) |
该属性定义实体之间的1:1\1:N\N:N关联关系. |
|
|
抓取属性(Fetched Properties) |
这是关联关系的可选方法,抓取属性允许在获联关联实体时执行某个过滤条件.
|
|
添加一个简单的实体
- 单击上图所示界面左下角的“Add Entity”按钮,系统将会在ENTITIES列表下添加一个实体,将该实体重命名为项目所需的名字,
- 此处重名为LCEvent。提示:“长按“Add Entity”按钮,该按钮将会显示Add Entity、Add Fetch Request、Add Configuration列表,
- 可以选择其中一项来添加实体、抓取请求、配置。”
- 选中LCEntity实体,通过单击上图所示界面右下角的“Add Attribute”按钮,系统将会为该LCEntity实体添加一个属性,
- 将该属性重名为项目所需的名字,此处重命名为name,并为该属性选择类型,此处选择String类型。
重复第2步,为该实体再次添加happenDate属性,并将该属性设置为Date类型。
实体设计完成后,将可以看到下图所示的效果

- 单击Xcode主菜单的”Editor” →”Create NSManagedObject Subclass”菜单项,如果系统包含两个以上实体,Xcode将会弹出一个
- 对话框让我们选择要为那些实体生成NSManagedObject的子类,然后弹出对话框让我们选择NSManagedObject的子类测存储路径.
该实体包含两个属性,但不包含任何关联关系.
使用Core Data实现数据的增、删、改、查
添加实体
|
1 |
调用NSEntityDescription的insertNewObjectForEntityForName:inManagedObjectContext:静态方法添加新实体.该方法的第1个参数为实体名,第2个参数为NSManagedObjectContext对象 |
|
2 |
为新实体设置属性 |
|
3 |
调用NSManagedObjectContext对象的save:方法执行保存. |
|
代码片段 |
//控制Core Data在托管对象上下文中创建一个新实体
LCEvent *event = [NSEntityDescription insertNewObjectForEntityForName:@”LCEvent”
inManagedObjectContext:self.appDelegate.managedObjectContext];
//为新实体设置属性
. . .
//定义一个NSError对象,用于接收错误信息
NSError *error;
//设置完实体属性之后,调用托管对象上下文的save:方法将实体写入数据库.如果保存成功
if ([self.appDelegate.managedObjectContext save:&error])
{
. . .
}
else
{
NSLog(@”保存实体出错: %@,%@”,error, [error userInfo]);
}
|
删除实体
删除实体的步骤如下
|
1 |
获取要删除的实体 |
|
2 |
调用NSManagedObjectContext对象的deleteObject:方法删除实体. |
|
3 |
调用NSManagedObjectContext对象的save:方法执行保存. |
|
代码片段 |
//获取将要删除的实体
LCEvent *deleteEvent = . . .;
//从托管对象上下文中删除指定对象
[self.appDelegate.managedObjectContext deleteObject:deleteEvent];
// 定义一个NSError对象,用于接收错误信息
NSError *error;
// 保存删除操作,如果出现错误,则显示错误信息
if(![self.appDelegate.managedObjectContext save:&error])
{
NSLog(@”删除实体出错: %@,%@”,error,[error userInfo]);
}
|
修改实体
修改实体的步骤如下
|
1 |
获取要修改的实体(必须是处于NSManagedObjectContext管理下的实体) |
|
2 |
修改实体的属性. |
|
3 |
调用NSManagedObjectContext对象的save:方法执行保存. |
|
代码片段 |
//获取将要修改的实体
LCEvent *updateEvent = . . .;
//从托管对象上下文中删除指定对象
. . .
// 定义一个NSError对象,用于接收错误信息
NSError *error;
// 保存删除操作,如果出现错误,则显示错误信息
if(![self.appDelegate.managedObjectContext save:&error])
{
NSLog(@”删除实体出错: %@,%@”,error,[error userInfo]);
}
|
查询实体
查询实体的步骤如下.
|
1 |
创建NSFetchRequest对象 |
|
|
2 |
通过NSEntityDescription对象设置NSFetchRequest对象将要抓取的实体 |
|
|
3 |
如果需要对抓取结果进行筛选,则需要通过NSPredicate(谓词)对象设置筛选条件.如果需要对结果进行排序,还需要为NSFetchRequest添加多个NSSortDescription对象 |
|
|
4 |
调用NSManagedObjectContext对象的executeFetchRequest:error:方法执行查询,该查询方法将会返回所有符合条件的实体组成的NSArray集合 |
|
|
代码片段 |
// 创建抓取数据的请求对象 NSFetchRequest *request = [[NSFetchRequest alloc] init]; // 设置要抓取哪种类型的实体 NSEntityDescription *entity = [NSEntityDescription entityForName:@”LCEvent” inManagedObjectContext:self.appDelegate.managedObjectContext]; // 设置抓取实体 [request setEntity:entity]; // 定义抓取条件 request.predicate = [NSPredicate predicateWithFormat:. . .]; NSError *error = nil; // 执行抓取数据的请求,返回符合条件的数据 NSArray *array = [[self.appDelegate.managedObjectContext executeFetchRequest:request error:&error] mutableCopy]; |
|
管理实体的关联关系
Core Data除了可用于管理单独的实体之外,还可以用于管理实体与实体之间的关联关系.新建一个项目,并通过勾选”Use Core Data”选项来初始化
Core Data应用----通过这种方式创建的项目,Xcode已经为项目做好了如下准备工作
- 添加了CoreData.framework框架.
- 添加了一个空的.xcdatamodeld实体设计文件.
- 在应用程序委托类中为Core Data的3个API定义了属性,并提供了方法执行初始化.
- 重写了应用委托类的- (void)applicationwillTerminate:(UIApplication *)application方法,并在该方法中调用了托管对象上下文的save:方法执行保存.
iOS-Core Data 详解的更多相关文章
- IOS 数据存储之 Core Data详解
Core Date是ios3.0后引入的数据持久化解决方案,它是是苹果官方推荐使用的,不需要借助第三方框架.Core Date实际上是对SQLite的封装,提供了更高级的持久化方式.在对数据库操作时, ...
- iOS应用开发详解
<iOS应用开发详解> 基本信息 作者: 郭宏志 出版社:电子工业出版社 ISBN:9787121207075 上架时间:2013-6-28 出版日期:2013 年7月 开本:16开 ...
- 【转】段错误调试神器 - Core Dump详解
from:http://www.embeddedlinux.org.cn/html/jishuzixun/201307/08-2594.html 段错误调试神器 - Core Dump详解 来源:互联 ...
- iOS中-Qutarz2D详解及使用
在iOS中Qutarz2D 详解及使用 (一)初识 介绍 Quartz 2D是二维绘图引擎. 能完成的工作有: 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片(图像) 读取\生成 ...
- 了解iOS消息推送一文就够:史上最全iOS Push技术详解
本文作者:陈裕发, 腾讯系统测试工程师,由腾讯WeTest整理发表. 1.引言 开发iOS系统中的Push推送,通常有以下3种情况: 1)在线Push:比如QQ.微信等IM界面处于前台时,聊天消息和指 ...
- 转载]IOS LBS功能详解[0](获取经纬度)[1](获取当前地理位置文本 )
原文地址:IOS LBS功能详解[0](获取经纬度)[1](获取当前地理位置文本作者:佐佐木小次郎 因为最近项目上要用有关LBS的功能.于是我便做一下预研. 一般说来LBS功能一般分为两块:一块是地理 ...
- iOS 2D绘图详解(Quartz 2D)之路径(点,直线,虚线,曲线,圆弧,椭圆,矩形)
前言:一个路径可以包含由一个或者多个shape以及子路径subpath,quartz提供了很多方便的shape可以直接调用.例如:point,line,Arc(圆弧),Curves(曲线),Ellip ...
- iOS开发——Block详解
iOS开发--Block详解 1. Block是什么 代码块 匿名函数 闭包--能够读取其他函数内部变量的函数 函数变量 实现基于指针和函数指针 实现回调的机制 Block是一个非常有特色的语法,它可 ...
- iOS开发:详解Objective-C runTime
Objective-C总Runtime的那点事儿(一)消息机制 最近在找工作,Objective-C中的Runtime是经常被问到的一个问题,几乎是面试大公司必问的一个问题.当然还有一些其他问题也几乎 ...
随机推荐
- 读取Jar中的json文件
现在操作json的jar 都是用的fastjson, 如果需要读取的json文件不在jar包里面,则可以这样获取到: String path = this.getClass().getClassLoa ...
- git 常用命令速查
git 常用命令速查 命令速查表 一.克隆项目 把远程仓库上的项目克隆到本地.一般来说项目是有1个或2个分支,主要是做开发和线上的区别.既然所属分支不一样,那命令也会有一点区别.这里假设是有2个分支, ...
- Examining the Rooms - 第一类斯特灵数
---恢复内容开始--- 2017-08-10 20:32:37 writer:pprp 题意如下: Recently in Teddy's hometown there is a competiti ...
- cocos2d-x入门二 helloworld实例运行与创建
本机环境:win7+VS2012+python2.7.8+cocos2d-x-3.8,另外本机已经配置android开发环境(java+eclipse+SDK+ADT),针对环境搭建后续会有一篇详细说 ...
- vue.js学习之组件(上篇)
本文的Demo和源代码已放到GitHub,如果您觉得本篇内容不错,请点个赞,或在GitHub上加个星星! https://github.com/zwl-jasmine95/Vue_test 以下所有知 ...
- [mybatis]Record与Example的用法
一.Record 一个Record是一个Dao对象(继承Mapper接口),tkmybatis会将record自动映射成sql语句,record中所有非null的属性都作为sql语句,如: 映射的sq ...
- python脚本7_打印九九乘法表
#打印九九乘法表 for i in range(1,10): s = "" for j in range(1,i+1): s += str(j) + '*' + str(i) + ...
- vim 的寄存器
If you've been following my series on Vim, it should be clear now that Vim has a pretty clear philos ...
- Error:Cannot access first() element from an empty List
解决方案: bintray版本问题,修改为: classpath 'com.novoda:bintray-release:0.3.4' 如下: buildscript { repositories { ...
- mbstring.so下载安装
linux下安装: $:cd /php7.0/ext/mbstring 切换到源码包目录下 $:/usr/local/php/bin/phpize 执行这句 $:./configure –with-p ...




