博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据持久化(五)之CoreData
阅读量:4963 次
发布时间:2019-06-12

本文共 10041 字,大约阅读时间需要 33 分钟。

@简单的说,Core Data就是能够存储到磁盘的对象图,[...]Core Data能够帮我们做非常多任务作.它能够作为软件的整个模型层。

它不只在磁盘上存储数据。也把我们须要的数据对象读取到内存中。

                                                                                                                              ——Marcus Zarra, Core Data

@Core Data是Mac OS X中Cocoa API的一部分,首次在Mac OS X 10.4 Tiger与iOS 3.0系统中出现[2]。它同意依照实体-属性-值模型组织数据。并以XML,二进制文件或SQLite数据文件的格式将其串行化。Core Data同意用户使用代表实体和实体间关系的高层对象来操作数据。它也能够管理串行化的数据,提供对象生存期管理与object graph管理,包含存储。

Core Data直接与SQLite交互,避免开发人员使用原本的SQL语句,就像Cocoa绑定在模型-视图-控制器设计中做了非常多控制器的工作一样,Core Data做了非常多数据模型的工作。它的主要任务是负责数据更改的管理。串行化到磁盘。最小化内存占用,以及查询数据。

@http://www.cocoachina.com/iphonedev/sdk/2010/1126/2397.html( 这是官方对于CoreData的说明)

@接下来,我就不利用框架自己主动生成代码,全然自己编写全部的 Core data 相关代码的命令行应用程序来深入解说 Core data的使用。

*概念图*

@加入CoreData框架,导入#import<CoreData/CoreData.h>

写代码之前须要了解6个对象:

(1)NSManagedObjectContext(被管理的数据上下文)

操作实际内容(操作持久层)
作用:插入数据,查询数据,删除数据
(2)NSManagedObjectModel(被管理的数据模型)
数据库全部表格或数据结构,包括各实体的定义信息
作用:加入实体的属性。建立属性之间的关系
操作方法:视图编辑器。或代码
(3)NSPersistentStoreCoordinator(持久化存储助理)
相当于数据库的连接器
作用:设置数据存储的名字。位置,存储方式,和存储时机
(4)NSManagedObject(被管理的数据记录)
相当于数据库中的表格记录
(5)NSFetchRequest(获取数据的请求)
相当于查询语句
(6)NSEntityDescription(实体结构)
相当于表格结构
(7)后缀为.xcdatamodeld的包
里面是.xcdatamodel文件,用数据模型编辑器编辑
编译后为.momd或.mom文件

1.自己定义封装的CoreData管理类HMTCoreDataManager

.h

#import 
#import
/** * 数据存储成功的代码块 */typedef void(^HandleSaveSuccessedBlock)();/** * 数据存储失败的代码块 */typedef void(^HandleSaveFailedBlock)(NSError *);@interface HMTCoreDataManager : NSObject@property (nonatomic,strong)NSManagedObjectContext *managedObjectContext; // 托管对象上下文/** * 创建一个单例对象 * * @return 单例对象 */+ (HMTCoreDataManager *)defaultManager;/** * 依据实体描写叙述获得托管对象 * * @param entityName 指定实体描写叙述名字 * @param aClass 要获取的托管对象 * * @return 托管对象实例 */- (NSManagedObject *)managedObjectWithEntityName:(NSString *)entityName managedObjectClass:(Class)aClass;/** * 数据存储到磁盘中成功和失败响应的方法,參数为2个block * * @param aSuccessedHandler * @param aFailedHandler */- (void)saveWithSuccessedHandler:(HandleSaveSuccessedBlock)aSuccessedHandler failedHandler:(HandleSaveFailedBlock)aFailedHandler;//  插入数据- (void)insertCoreData;//  查询- (NSMutableArray*)selectData:(NSString *)name;//  删除- (void)deleteData:(NSManagedObject *)object;//  更新- (void)updateData:(NSString* )newName;@end
.m

#import "HMTCoreDataManager.h"@interface HMTCoreDataManager ()@property (nonatomic,strong) NSPersistentStoreCoordinator *persistentStoreCoordinator;  //  持久化存储协调器@property (nonatomic,strong) NSManagedObjectModel * managedObjectModel;  //  托管对象模型@end@implementation HMTCoreDataManagerstatic HMTCoreDataManager *manager = nil;+ (HMTCoreDataManager *)defaultManager{    @synchronized(self){            if (manager == nil) {            manager = [[HMTCoreDataManager alloc] init];        }    }/*    //  通过GCD创建    static dispatch_once_t onceToken;    dispatch_once(&onceToken,^{            manager = [[HMTCoreDataManager alloc] init];            });*/    return manager;}#pragma mark - 属性的方便之处能在get方法中初始化/** *  非常多人对于这个上下文不太理解,開始我也不太理解,查了非常多资料,感觉以下这个解释比較通俗易懂 *  托管对象上下文: *  托管对象上下文包括全部的托管对象,这些托管对象已经为提交给数据库准备就绪,在托管对象上下文中。能够加入、改动和删除托管对象, *  这一层相当于应用程序和数据库之间的缓冲区。

*/ - (NSManagedObjectContext *)managedObjectContext{ if (_managedObjectContext) { return _managedObjectContext; } _managedObjectContext = [[NSManagedObjectContext alloc] init]; // 为托管对象上下文指定一个持久化存储协调器 [_managedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator]; return _managedObjectContext; } /** * 持久化存储协调器(持久化存储助理) * 持久化存储协调器处理到数据存储的连接,而且包括一些底层信息,像用到数据存储的名字和位置 * 一般我们无需与它直接打交道,上下文已经封装了对它的调用 */ - (NSPersistentStoreCoordinator *)persistentStoreCoordinator{ if (_persistentStoreCoordinator) { return _persistentStoreCoordinator; } // 初始化一个持久化存储协调器必须依赖NSManagedObjectModel _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel]; // 存储路径(返回的是NSURL类型)为Documents文件夹下。以及数据库名称 NSURL *documentURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; NSURL *fileURL = [documentURL URLByAppendingPathComponent:@"myClass.sqlite"]; NSError *error = nil; // 载入持久化存储数据(指定持久化存储的数据类型,默认的是NSSQLiteStoreType,即SQLite数据库) [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:fileURL options:nil error:&error]; if (error != nil) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"加入持久化存储失败" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; [alert show]; } return _persistentStoreCoordinator; } /** * 托管对象模型 * 数据库全部表格或数据结构包括各实体的定义信息 * 加入实体的属性,建立属性之间的关系 */ - (NSManagedObjectModel *)managedObjectModel{ if (_managedObjectModel) { return _managedObjectModel; } // 获取托管对象模型文件的地址 // 编译器会自己主动将"xcdatamodeld"格式转化为"momd" NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"myClassModel" withExtension:@"momd"]; _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; return _managedObjectModel; } - (NSManagedObject *)managedObjectWithEntityName:(NSString *)entityName managedObjectClass:(Class)aClass{ // 创建"HMTClass"的实体描写叙述 NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"HMTClassEntity" inManagedObjectContext:self.managedObjectContext]; // 通过"HMTClass"的实体描写叙述创建HMTClass的托管对象 NSManagedObject *managedObject = [[aClass alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:self.managedObjectContext]; return managedObject; } - (void)saveWithSuccessedHandler:(HandleSaveSuccessedBlock)aSuccessedHandler failedHandler:(HandleSaveFailedBlock)aFailedHandler{ NSError *error = nil; [self.managedObjectContext save:&error]; if (error != nil) { aFailedHandler(error); }else { aSuccessedHandler(); } } @end

2.创建模型文件
ManagedObject的过程

3.将创建的模型文件转化为相应的类文件

第一种:command+n

另外一种: 选中myClassModel.xcdatamodeld

之后都是一样的--->选中模型文件--->选中要创建的实体

最后,就会生成前面图片中的3个类,都是继承了NSManagedObject

------------------class-------------------------------@class HMTStudent, HMTTeacher;@interface HMTClass : NSManagedObject@property (nonatomic, retain) NSString * name;@property (nonatomic, retain) NSSet *students;@property (nonatomic, retain) HMTTeacher *teacher;@end@interface HMTClass (CoreDataGeneratedAccessors)- (void)addStudentsObject:(HMTStudent *)value;- (void)removeStudentsObject:(HMTStudent *)value;- (void)addStudents:(NSSet *)values;- (void)removeStudents:(NSSet *)values;@end#import "HMTClass.h"#import "HMTStudent.h"#import "HMTTeacher.h"@implementation HMTClass@dynamic name;@dynamic students;@dynamic teacher;@end------------------teacher-------------------------------@class HMTClass;@interface HMTTeacher : NSManagedObject@property (nonatomic, retain) NSString * name;@property (nonatomic, retain) NSString * course;@property (nonatomic, retain) HMTClass *myClass;@end#import "HMTTeacher.h"#import "HMTClass.h"@implementation HMTTeacher@dynamic name;@dynamic course;@dynamic myClass;@end------------------student-------------------------------@class HMTClass, HMTTeacher;@interface HMTStudent : NSManagedObject@property (nonatomic, retain) NSString * name;@property (nonatomic, retain) NSNumber * age;@property (nonatomic, retain) HMTTeacher *teacher;@property (nonatomic, retain) HMTClass *myClass;@end#import "HMTStudent.h"#import "HMTClass.h"#import "HMTTeacher.h"@implementation HMTStudent@dynamic name;@dynamic age;@dynamic teacher;@dynamic myClass;@end
4.准备工作都OK了,最后进行数据的持久化存储

#pragma mark - 增删改查//  插入数据操作(相似于FMDB做法,方法后面可带你想存储的数据对象,这里仅仅是单纯的演示)//   - (void)insertCoreData:(AppleClass *)appleClass- (void)insertCoreData{    //  创建"HMTClass"的实体描写叙述,传入的正是前面标注的实体描写叙述名    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"HMTClassEntity" inManagedObjectContext:self.managedObjectContext];        //  通过"HMTClass"的实体描写叙述创建HMTClass的托管对象    HMTClass *hmtClass = [[HMTClass alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:self.managedObjectContext];    //  hmtClass.name = appleClass.name;    hmtClass.name = @"Apple";        //  托管对象上下文将托管对象的更改保存到磁盘文件里    //  - save  将数据保存到数据库    NSError *error = nil;    [self.managedObjectContext save:&error];    if (error != nil) {        NSLog(@"加入失败:%@",[error localizedDescription]);    }}//  删除数据操作- (void)deleteData:(NSManagedObject *)object{    [self.managedObjectContext deleteObject:object];    NSError *error = nil;    [[HMTCoreDataManager defaultManager].managedObjectContext save:&error];    if (error != nil) {        NSLog(@"删除失败:%@",[error localizedDescription]);    }}//  查询数据操作(根据特定条件查询,假设是select * 就直接不写谓词推断语句)- (NSMutableArray*)selectData:(NSString *)name{    //  创建指定Entity的查询语句    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"HMTClassEntity"];        //  谓词,原理和使用方法都相似于SQL中的where,作用相当于数据库的过滤取(我blog中OC分类有详细讲到)    NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"name == \'%@\'",name],nil];    fetchRequest.predicate = predicate;        //  查询的结果按哪个key进行排序,YES为升序//    NSSortDescriptor *timestampSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"classNO" ascending:YES];//    fetchRequest.sortDescriptors = @[timestampSortDescriptor];        //  注意查询返回的仅仅能是NSArray类型    NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:nil];    NSMutableArray *resultArray = [NSMutableArray arrayWithArray:fetchedObjects];    return resultArray;}//  更新数据操作- (void)updateData:(NSString *)newName{    //  创建指定Entity的查询语句    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"HMTClassEntity"];        //  注意查询返回的仅仅能是NSArray类型    NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:nil];    //  更新    for (HMTClass *info in fetchedObjects) {        info.name = newName;    }        //保存    if ([self.managedObjectContext save:nil]) {        //更新成功        NSLog(@"更新成功");    }}

@转载请注明:http://blog.csdn.net/hmt20130412  谢谢!

@不错的CoreData资料:

    http://blog.csdn.net/rhljiayou/article/details/18037729

    http://blog.csdn.net/kesalin/article/details/6739319

    http://www.cnblogs.com/mybkn/articles/2472881.html

转载于:https://www.cnblogs.com/bhlsheji/p/5354604.html

你可能感兴趣的文章
Cookie、Session和自定义分页
查看>>
cocos2d-x场景间参数传递
查看>>
一个误解: 单个服务器程序可承受最大连接数“理论”上是“65535”
查看>>
58笔部分试题--前端
查看>>
Storm基本原理概念及基本使用
查看>>
十一周
查看>>
antd button
查看>>
JavaScript——数组的indexOf()方法在IE8中的兼容性问题
查看>>
散列表(一).散列表基本内容介绍
查看>>
css3 media媒体查询器用法总结
查看>>
python restful 框架之 eve 外网访问设置
查看>>
Laravel
查看>>
我的编程概念
查看>>
C. Sereja and Algorithm 贪心
查看>>
Java maven 开发环境搭建
查看>>
ZOJ 2836 Number Puzzle
查看>>
【转】从Mac/OS和iOS开放源码浅谈UNIX家谱
查看>>
ShaderForge插件的基础使用
查看>>
linux系统常见错误汇总
查看>>
web前端历史的总结
查看>>