"Care Data
是一个纯粹的面向对象框架,可用于管理实体以及实体之间的关联关系的持久化,也就是我们通常所指的数据持久化。"
##1.原理部分
Care Data
是一个纯粹的面向对象框架,可用于管理实体以及实体之间的关联关系的持久化,也就是我们通常所指的数据持久化。
Care Data
底层的持久化存储方式可以是SQLite
数据库,也可以是XML
文档,甚至可以直接以内存作为持久化存储设备。
Care Data
的核心概念是实体。实体是由Care Data
管理的模型对象,它必须是NSManagedObject
类或其子类的实例。
实体与实体之间存在1-1、1-N、N-N、的关联关系,整个应用的所有实体以及实体之间的关联关系被称为托管对象模型NSManagedObiectModel
。
Care Data
的核心对象是托管对象上下文NSManagedObjectContext
,所有实体都处于托管对象上下文管理中,
Care Data
应用对实体所做的任何增、删、查、改操作都必须通过托管对象上下文来完成。
开发者开发的应用程序需要通过NSMannagedObjectContext
对实体进行增、删、查、改操作,
而NSMannagedObjectContext
底层与持久化存储协调衔接,持久化存储协调器则负责管理底层的存
储形式比如:SQLite
。
Care Data
应用中的核心API
有如下几个。
托管对象模型NSManagedObiectModel
:该对象负责管理整个应用的所有实体以及实体之间的关联关系。当开发者使用Xcode
的图形界面设计了实体与实体的关联关系之后,需要使用该对象来加载、管理应用的托管对象模型。
持久化存储协调器NSPeristentStoreCoordinator
:负责管理底层的存储文件,例如SQLite
数据库等。
托管对象上下文NSManagedObjectContext
:该对象是Care Data
的核心对象,应用对实体所做的任何增、删、查、改操作都必须通过该对象来完成。
实体描述NSEntityDescription
:该对象代表了关于某个实体的描述信息,从某种程度来说,该对象相当于实体的抽象。实体描述定义了该实体的名字、实体的实现类,并用一个集合定义了该实体包含的所有属性。
抓取请求NSFetchRequest
:该对象封装了查询实体的请求,包括程序需要查询哪些实体、查询条件、排序规则等。抓取请求定义了本次查询的实体的名字、抓取请求的查询条件,通过NSPredicate来表示
,并用一个NSArray
集合定义了所有的排序规则。
####熟悉以上几点之后,使用Core Data
持久化操作的步骤大致如下。
创建NSManagedObiectModel
对象来加载管理应用的托管对象模型。
以NSManagedObiectModel
对象为基础,根据实际需要创建NSPeristentStoreCoordinator
对象,该对象确定Core Data
底层数据的存储形式。
以NSManagedObiectModel
对象为基础,创建NSMannagedObjectContext
,该对象是Core Data
进行持久化访问的核心对象。
对于普通的增、删、查、改操作,需要分别先创建实体、删除实体、修改实体,然后调用NSMannagedObjectContext
对象的save:
方法将这些修改保存到底层存储设备。
如果要执行查询,则需要先创建NSFetchRequest
对象,再调用NSMannagedObjectContext
的executeFetchRequest:error
:方法执行查询,该方法返回所有匹配条件的实体组成的NSArray
。
##2.手动配置环境
iOS允许在创建项目时勾选“Use Core Data”复选框,通过该方式创建的项目已经完成了所有
Core Data
必须资源的初始化,但此处并不打算使用这种方式来初始化Core Data
项目,
而是选择从一个Empty Application
开始,手动初始化Core Data
项目,这样便于大家真
正理解Care Data
项目需要初始化哪些资源。
下面我们将开始把这个Empty Application
项目一步步改造成Core Data
项目。
具体步骤如下:
为该项目添加CoreData.framework
框架。
为该项目添加一个实体模型文件。单击Xcode主菜单的”File”—>”New”—>”File”菜单项,具体如下图:
在AppDelegate
中初始化Core Data
应用必须的核心API
对象:
NSManagedObiectModel
、NSPeristentStoreCoordinator
、NSManagedObjectContext
修改应用程序委托类的接口部分,在接口部分定义上面3个核心API
的属性,并增加一个对
NSManagedObjectContext
对象执行存储的方法、一个获取应用Docouments
目录下的方法。
下面是修改后的接口部分代码。
AppDelegate.h
#import < UIKit / UIKit .h >
#import < CoreData / CoreData .h >
@interface AppDelegate : UIResponder < UIApplicationDelegate >
@ property ( strong , nonatomic ) UIWindow * window ;
// 定义Core Data的3个核心API的属性
@property ( readonly , strong , nonatomic ) NSManagedObjectContext *
managedObjectContext ;
@property ( readonly , strong , nonatomic ) NSManagedObjectModel * managedObjectModel ;
@property ( readonly , strong , nonatomic ) NSPersistentStoreCoordinator *
persistentStoreCoordinator ;
- ( void ) saveContext ;
- ( NSURL *) applicationDocumentsDirectory ;
@end
接下来在AppDelegate.m
中实现部分进行修改,初始化对象,并实现saveContext
方法,
其中applicationDocumentsDirectory
是一个非常简单的方法,用于获取应用Docouments
目录
AppDelegate.m
@synthesize managedObjectContext = _managedObjectContext ;
@synthesize managedObjectModel = _managedObjectModel ;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator ;
- ( BOOL ) application :( UIApplication *) application
didFinishLaunchingWithOptions :( NSDictionary *) launchOptions
{
return YES;
}
- ( void ) applicationWillTerminate :( UIApplication *) application
{
// 当应用被中断时候,将所有托管上下文中数据保存起来
[self saveContext];
}
- ( void ) saveContext
{
NSError *error = nil;
// 获取应用的托管对象上下文
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil)
{
// 如果托管对象上下文中包含了未保存的修改,执行保存,如果保存失败记录错误信息
if ([managedObjectContext hasChanges] &&
![managedObjectContext save : & error ])
{
NSLog ( @ "保存出现错误:%@, %@" , error , [ error userInfo ]);
abort();
}
}
}
// 初始化应用的托管对象上下文 。
- ( NSManagedObjectContext *) managedObjectContext
{
// 如果_managedObjectContext已经被初始化过,直接返回该对象
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
// 获取持久化存储协调器
NSPersistentStoreCoordinator * coordinator = [ self persistentStoreCoordinator ];
// 如果持久化存储协调器不为nil
if ( coordinator != nil )
{
// 创建NSManagedObjectContext对象
_managedObjectContext = [[NSManagedObjectContext alloc] init];
// 为NSManagedObjectContext对象设置持久化存储协调器
[_managedObjectContext setPersistentStoreCoordinator : coordinator ];
}
return _managedObjectContext ;
}
- ( NSManagedObjectModel *) managedObjectModel
{
// 如果_managedObjectModel已经被初始化过,直接返回该对象
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
// 获取实体模型文件对应的NSURL
NSURL * modelURL = [[ NSBundle mainBundle ] URLForResource :@ "FKModel"
withExtension :@ "momd" ];
// 加载应用的实体模型文件 , 并初始化NSManagedObjectModel对象
_managedObjectModel = [[ NSManagedObjectModel alloc ]
initWithContentsOfURL :modelURL ];
return _managedObjectModel ;
}
- ( NSPersistentStoreCoordinator *) persistentStoreCoordinator
{
// 如果_persistentStoreCoordinator已经被初始化过,直接返回该对象
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
// 获取SQLite数据库文件的存储目录
NSURL * storeURL = [[ self applicationDocumentsDirectory ]
URLByAppendingPathComponent :@ "Books.sqlite" ];
NSError * error = nil ;
// 以持久化对象模型为基础 , 创建NSPersistentStoreCoordinator对象
_persistentStoreCoordinator = [[ NSPersistentStoreCoordinator alloc ]
initWithManagedObjectModel :[ self managedObjectModel ]];
// 设置持久化存储协调器底层采用SQLite存储机制 , 如果设置失败记录错误信息
if (![ _persistentStoreCoordinator addPersistentStoreWithType :NSSQLiteStoreType
configuration :nil URL :storeURL options :nil error :& error ])
{
NSLog(@"设置持久化存储失败:%@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator ;
}
// 获取应用的Documents目录
- ( NSURL *) applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory : NSDocumentDirectory
inDomains : NSUserDomainMask ] lastObject ];
}
到此Core Data
所依赖的环境基本上已经搭建完毕,应用执行增、删、查、改操作直接调用
managedObjectContext
方法即可操作。
##3.设计实体模型
Xcode中找到我们创建的Core Data
文件,打开实体模型开始编辑,具体如下图:
下面我们添加一个简单的实体,点击上图走下角的Add Entity
,系统将会在ENTITIES
列表下添加一个实体,
将该实体重命名为项目所需的名字,此处为Bison
####PS长按Add Entity
将会显示Add Entity
、Add Fetch Request
、Add Configuration
列表,可供选择添加实体、抓取请求、配置。
选中Bison
实体,通过点击上图右下角的Add Attribute
按钮,系统将会为该Bison
实体添加一个属性,
将该属性重命名所需的名字,此处重命名name
,并为该属性选择类型,在此选String
类型,注意:此处命名
首字母不能大写哦。
####PS长按Add Attribute
将会显示Add Attribute
、Add Relationship
、Add Configuration
、Add Fetch Property列表,可供选择添加属性、关联关系、抓取属性,也可以通过 +
、—
来添加与删除。
重复上面的操作增加一个birthDay
的属性,改属性为date
类型。实体设计完后,如下图:
然后单击Xcode主菜单的Editor
–>Create NSManagedObject Subclass
菜单项,
如果系统包含俩个以上的实体,Xcode将会弹出一个对话框让选择腰围哪些实体生成NSManagedObject
的子类,然后弹出对话框让选择NSManagedObject
的子类的存储路径。选完之后Create
按钮即可。
经过上面的操作,为实体模型添加一个简单的Bison
实体,该实体包含俩个属性,单不包含任何关联关系。
##4.Core Data
数据的增删查改
获取托管对象上下文NSManagedObjectContext
之后,接下来即可通过该对象来执行增、删、查、改操作。
添加实体
添加实体的步骤如下:
调用NSEntityDescription
的insertNewObjectForEntityForName:inManagedObjectContext:
静态方法添加新实体。该方法的第1个参数为实体名,第2个参数为NSManagedObjectContext
对象。
为新实体设置属性。调用NSManagedObjectContext
对象的save:
方法执行保存。如下代码片段:
// 控制Core Data在托管对象上下文中创建一个新实体
Bison * bison = [ NSEntityDescription
insertNewObjectForEntityForName :@ "Bison"
inManagedObjectContext :self .appDelegate.managedObjectContext ];
// 为新实体设置属性
bison .name = @ "linbin" ;
bison .birth_Day = [ NSDate date ];
// 定义一个NSError对象 , 用于接受错误信息
NSError * error ;
// 设置完实体属性之后 , 调用托管对象上下文的 ` save : ` 方法将实体写入数据库 , 如果保存成功
if ([ self .appDelegate.managedObjectContext save :& error ])
{
[[[UIActionSheet alloc] initWithTitle : @ "保存成功" delegate : nil
cancelButtonTitle : @ "确定" destructiveButtonTitle : nil
otherButtonTitles : nil ] showInView : self . view ];
} else {
NSLog(@" 保存FKEvent实体出错 : %@ , %@" , error ,[ error userInfo ]);
}
删除实体
删除实体的步骤如下:
首先获取要删除的实体,然后调用NSManagedObjectContext
对象的deleteObject:
方法删除实体。最后调用NSManagedObjectContext
对象的save:
方法执行保存。
如下代码:
// 获取将要删除的实体
Bison * deleteEvent = .....;
// 从托管对象上下文中删除指定对象
[ self .appDelegate.managedObjectContext deleteObject :deleteEvent ];
NSError * error ;
// 保存删除操作 , 如果出现错误 , 显示错误信息
if (![ self .appDelegate.managedObjectContext save :& error ])
{
NSLog(@" 删除FKEvent实体出错 : %@ , %@" , error ,[ error userInfo ]);
}
修改实体
修改实体的步骤如下:
首先获取要修改的实体,必须处于NSManagedObjectContext
管理下的实体;然后修改实体的属性;再调用NSManagedObjectContext
对象的save:
方法执行保存。如下代码:
// 获取将要修改的实体
Bison * updateEvent = .....;
// 修改实体的属性
.....
// 定义一个NSError对象 , 用于接收错误信息
NSError * error ;
// 保存修改操作 , 如果出现错误 , 显示错误信息
if (![ self .appDelegate.managedObjectContext save :& error ])
{
NSLog(@" 删除FKEvent实体出错 : %@ , %@" , error ,[ error userInfo ]);
}
查询实体
查询实体的步骤如下:
首先创建NSFetchRequest
对象。然后通过NSEntityDescription
对象设置
NSFetchRequest
对象将要抓取的实体。如果需要对抓取结果进行筛选,则需要
通过NSPredicate
对象设置筛选条件。如果需要对结果进行排序,还需要为
NSFetchRequest
添加多个NSSortDescriptor
对象。再调用
NSManagedObjectContext
对象的executeFetchRequest:error:
方法执行查询,该查询方法将会返回所有符合条件的实体组成的NSArray
集合。
如下代码:
// 创建抓取数据的请求对象
NSFetchRequest * request = [[ NSFetchRequest alloc ] init ];
// 设置要抓取哪种类型的实体
NSEntityDescription * entity = [ NSEntityDescription entityForName :@ "Bison"
inManagedObjectContext :self .appDelegate.managedObjectContext ];
// 设置抓取实体
[ request setEntity :entity ];
NSError * error = nil ;
// 执行抓取数据的请求 , 返回符合条件的数据
eventArray = [[ self .appDelegate.managedObjectContext
executeFetchRequest :request error :& error ] mutableCopy ];
基本的方法到此就结束了,具体的详情可以下载Demo查看
下载地址
博主app上线啦,快点此来围观吧
更多经验请点击
好文推荐:仿window阿里旺旺登陆界面,打印机吐纸动画效果
原文地址:http://allluckly.cn
版权归©Bison所有 如需转载请保留原文超链接地址!否则后果自负!