Core Data是有苹果官方提供的框架(#import <CoreData/CoreData.h>
),实现数据持久化存储。Core Data实际上是将数据库的创建、表的创建、对象和表的转换等操作封装起来,极大的简化了操作。使用Core Data进⾏数据库存取不需要手动创建数据库,创建数据库的过程完全由Core Data框架自动完成,使用者需要做的就是把模型创建起来。
Core Date与SQLite相比较,SQLite比较原始,操作比较复杂,使用的是C的函数对数据库进行操作,但是SQLite可控性更强,并且能够跨平台。
以下是Core Data操作中经常使用的几个类:
1、NSManagedObjectModel:被管理的对象模型,相当于实体,不过它包含 了实体间的关系。
2、NSManagedObjectContext:被管理的对象上下文,相当于操作实际内容 作用:插入数据 查询 更新 删除
。
3、NSPersistentStoreCoordinator:持久化存储助理,用于数据库的连接器。
4、NSFetchRequest :获取数据的请求,用于数据查询,相当于查询语句。
5、NSPredicate:相当于查询条件。
6、NSEntityDescription:实体结构。下面,讲解Core Data的简单使用
图一:创建工程在创建项目的时候可以选择使用Core Data,项目创建成功后,在AppDelegate类中系统会自动添加相关代码,此外,还会自动生成一个数据模型文件
工程名.xcdatamodeld
AppDelegate.h类中对应生成的代码:
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
//系统自动引入类
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (readonly, strong) NSPersistentContainer *persistentContainer;
- (void)saveContext;
@end
AppDelegate.m类中对应生成的代码,此处注意在XCode中自动生成的代码较之前有所变动:
#pragma mark - Core Data stack
@synthesize persistentContainer = _persistentContainer;
- (NSPersistentContainer *)persistentContainer {
// The persistent container for the application. This implementation creates and returns a container, having loaded the store for the application to it.
@synchronized (self) {
if (_persistentContainer == nil) {
_persistentContainer = [[NSPersistentContainer alloc] initWithName:@"_23"];
[_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) {
if (error != nil) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
NSLog(@"Unresolved error %@, %@", error, error.userInfo);
abort();
}
}];
}
}
return _persistentContainer;
}
#pragma mark - Core Data Saving support
- (void)saveContext {
NSManagedObjectContext *context = self.persistentContainer.viewContext;
NSError *error = nil;
if ([context hasChanges] && ![context save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, error.userInfo);
abort();
}
}
图二如果在创建项目的时候没有勾选Use Core Data选项,但是在后面需要使用,需要手动添加一个Data Model文件和手动的添加AppDelegate中的相关代码
注:创建Data Model文件时需要注意,文件名称要与AppDelegate.m中managedObjectModel方法中提到的文件名称相匹配,ios8的Xcode排版发生了一些变动,需要注意
图三 图四在生成Data Model文件后,在~~.xcdatamodeld里面添加实体和关系添加实体如图所示:
注:这里实际上就是向数据库中添加表格和建立表格之间的关联
完成以上步骤,数据库中表格的创建就已经完成,和使用SQLite比较,省略了sql语句以及调用C函数操作数据库的步骤,另外,在创建实体的时候不需要设置主键,实体对象的属性的类型是OC的类型,实体中其他实体对象类型是通过建立关系添加的。
图五创建好实体后,可以通过添加NSManagedObject subclass文件(注:创建模型对象的类, "Editor > Create NSManagedobject Subclass"。),系统可以自动添加实体对应的数据模型类,如图所示:
图六
图七
图八
图九
以下是封装好的CoreDataManaer单例文件
#import <Foundation/Foundation.h>
@interface CoreDataManager : NSObject
/**
* 单例的初始化类方法
*
* @return CoreDataManager
*/
+ (CoreDataManager *)defaultManager;
/**
* 添加一个对象模型到数据库中
*
* @param name 模型类的名字
* @param dictionary 需要对应赋值的属性
*/
- (void)addManagedObjectModelWithName:(NSString *)name dictionary:(NSDictionary *)dictionary;
/**
* 查询对象模型
*
* @param name 模型类的名字
* @param predicate 创建一个谓词
* @param sortkeys 用来排序的Keys(注意是个数组)
*
* @return 返回查到的对象, 在外部使用时应与name对应
*/
- (NSArray *)fetchManagedObjectModelWithName:(NSString *)name predicate:(NSPredicate *)predicate sortKeys:(NSArray *)sortkeys;
/**
* 删除对象模型
*
* @param models 对象模型数组(注意是数组, 尽管是删除一个也要数组)
*/
- (void)deleteAllManagedObjectModels:(NSArray *)models;
@end
#import "CoreDataManager.h"
#import <CoreData/CoreData.h>
@interface CoreDataManager ()
@property (nonatomic, strong) NSManagedObjectContext * managedObjectContext;
@property (nonatomic, strong) NSManagedObjectModel * managedObjectModel;
@property (nonatomic, strong) NSPersistentStoreCoordinator * persistentStoreCoordinator;
@end
@implementation CoreDataManager
static CoreDataManager * s_defaultManager = nil;
+ (CoreDataManager *)defaultManager {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
s_defaultManager = [[CoreDataManager alloc] init];
});
return s_defaultManager;
}
/**
* 单例的初始化方法, 在init方法中初始化单例类持有的对象
*
* @return 初始化后的对象
*/
- (instancetype)init
{
self = [super init];
if (self) {
// 添加观察者, 当ManagerObjectContext发生变化时调用saveContext方法
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveContext) name:NSManagedObjectContextObjectsDidChangeNotification object:nil];
}
return self;
}
- (void)addManagedObjectModelWithName:(NSString *)name dictionary:(NSDictionary *)dictionary {
NSManagedObject * managerObject = [NSEntityDescription insertNewObjectForEntityForName:name inManagedObjectContext:self.managedObjectContext];
[managerObject setValuesForKeysWithDictionary:dictionary];
}
- (NSArray *)fetchManagedObjectModelWithName:(NSString *)name predicate:(NSPredicate *)predicate sortKeys:(NSArray *)sortkeys {
// 实例化查询请求
NSFetchRequest * fetchRequest = [NSFetchRequest fetchRequestWithEntityName:name];
// 谓词搜索如果没有谓词, 那么默认查询全部
if (predicate) {
[fetchRequest setPredicate:predicate];
}
// 如果没有用来排序的key, 那么默认不排序
if (sortkeys) {
// 如果有排序的Key就先创建一个数组来接收多个NSSortDescriptor对象(尽管是一个, 因为setSortDescriptors:方法需要数组作为参数)
NSMutableArray * sortDescriptorKeys = [NSMutableArray new];
// 遍历所有的用来排序的key
for (NSString * key in sortkeys) {
// 每有一个Key, 就使用该key来创建一个NSSortDescriptor
NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:key ascending:YES];
// 在sortDescriptorKeys数组中添加一个NSSortDescriptor元素
[sortDescriptorKeys addObject:sortDescriptor];
}
// 查询请求设置排序方式
[fetchRequest setSortDescriptors:sortDescriptorKeys];
}
// 使用数组来接收查询到的内容
NSArray * fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:nil];
// 如果数组为nil
if (fetchedObjects == nil) {
// 创建一个新的数组返回, 在外部去做判断
fetchedObjects = [NSArray new];
}
// 返回查找到的数组
return fetchedObjects;
}
- (void)deleteAllManagedObjectModels:(NSArray *)models {
// 遍历删除传进来数组中的元素对应的表内容
for (NSManagedObject * object in models) {
// 使用管理者删除对象, 数组中的元素并没有缺少
[self.managedObjectContext deleteObject:object];
}
}
#pragma mark - Core Data stack
- (NSURL *)applicationDocumentsDirectory {
// NSLog(@"%@", [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]);
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
/**
* 模型器的懒加载方法
*
* @return 唯一的模型器
*/
- (NSManagedObjectModel *)managedObjectModel {
if (!_managedObjectModel) {
NSURL * momdPath = [[NSBundle mainBundle] URLForResource:@"PetEfamily" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momdPath];
}
return _managedObjectModel;
}
/**
* 链接器的懒加载方法
*
* @return 唯一的链接器对象
*/
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (!_persistentStoreCoordinator) {
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"LOCoreDataSample.sqlite"];
[_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:@{NSInferMappingModelAutomaticallyOption : @YES, NSMigratePersistentStoresAutomaticallyOption : @YES } error:nil];
}
return _persistentStoreCoordinator;
}
/**
* 管理者的懒加载方法
*
* @return 唯一的管理者对象
*/
- (NSManagedObjectContext *)managedObjectContext {
if (!_managedObjectContext) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:[self persistentStoreCoordinator]];
}
return _managedObjectContext;
}
/**
* ManagerObjectContext的保存方法
*/
- (void)saveContext {
[self.managedObjectContext save:nil];
}
@end
网友评论