详解持久化Core Data框架的原理以及使用

商鸿哲
2023-12-01
"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”菜单项,具体如下图:

1

  • 在AppDelegate中初始化Core Data应用必须的核心API 对象:
    NSManagedObiectModel、NSPeristentStoreCoordinator、NSManagedObjectContext
    修改应用程序委托类的接口部分,在接口部分定义上面3个核心API的属性,并增加一个对
    NSManagedObjectContext 对象执行存储的方法、一个获取应用Docouments目录下的方法。
    下面是修改后的接口部分代码。

AppDelegate.h

import

import

3.设计实体模型

Xcode中找到我们创建的Core Data文件,打开实体模型开始编辑,具体如下图:

2

下面我们添加一个简单的实体,点击上图走下角的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类型。实体设计完后,如下图:
3
然后单击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];

 类似资料: