@简单的说,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 <Foundation/Foundation.h>
#import <CoreData/CoreData.h>/*** 数据存储成功的代码块*/
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
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