之前介绍的是创建工程时直接勾选User Core Data的方式自动集成CoreData
如果是项目中期需要采用CoreData来管理数据,最简单的方式
1.直接从集成了CoreData的项目中,把AppDelegate中的代码拷贝到自己的工程中(如果没有就新建一个拷贝过去)
创建工程自动导入CoreData的方式,系统默认将代码生成在了AppDelegate中,为了提高代码的阅读性,同时在使用上下文时稍微简便一些,我们可以直接创建一个CoreData数据管理的单例工具类
头文件
.h文件中声明的属性和方法:
// 数据上下文 直接负责数据的增删改查
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
// 数据模型 对应的数据模型文件(.xcdatamodeld)
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
// 持久化存储协调器
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
// 保存上下文 增删改查后,必须保存上下文,持久化协调器才会将数据和数据库同步
- (void)saveContext;
// 沙盒Documents路径 CoreData生成的数据库默认就在Documents中
- (NSURL *)applicationDocumentsDirectory;
.m部分
#pragma mark - Core Data stack
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
- (NSURL *)applicationDocumentsDirectory {
// The directory the application uses to store the Core Data store file. This code uses a directory named "---ShenYJ---._1_Core_Data" in the application's documents directory.
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
- (NSManagedObjectModel *)managedObjectModel {
// The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"_1_Core_Data" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it.
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
// Create the coordinator and store
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"_1_Core_Data.sqlite"];
NSError *error = nil;
NSString *failureReason = @"There was an error creating or loading the application's saved data.";
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// Report any error we got.
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
dict[NSLocalizedFailureReasonErrorKey] = failureReason;
dict[NSUnderlyingErrorKey] = error;
error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
// Replace this 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();
}
return _persistentStoreCoordinator;
}
- (NSManagedObjectContext *)managedObjectContext {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (!coordinator) {
return nil;
}
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
return _managedObjectContext;
}
#pragma mark - Core Data Saving support
- (void)saveContext {
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
NSError *error = nil;
if ([managedObjectContext hasChanges] && ![managedObjectContext 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();
}
}
}
2.手动创建模型文件
接下来选择路径,这样模型文件就手动创建完成了,接下来就是创建实体Entity,字段Attribute(注意:Attribute 需要小写字母开头)
数据库管理单例工具类:
.h
#import
#import
@interface JSCoreDataManager : NSObject
// 数据上下文 直接负责数据的增删改查
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
// 数据模型 对应的数据模型文件(.xcdatamodeld)
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
// 持久化存储协调器
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
// 保存上下文 增删改查后,必须保存上下文,持久化协调器才会将数据和数据库同步
- (void)saveContext;
// 沙盒Documents路径 CoreData生成的数据库默认就在Documents中
- (NSURL *)applicationDocumentsDirectory;
// 单例
+ (instancetype)sharedCoreDataManager;
@end
.m
#import "JSCoreDataManager.h"
static JSCoreDataManager *_instanceType = nil;
@implementation JSCoreDataManager
+ (instancetype)sharedCoreDataManager{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instanceType = [[JSCoreDataManager alloc]init];
});
return _instanceType;
}
#pragma mark - Core Data stack
/* 手动生成成员变量
因为.h中声明的属性使用了readOnly修饰,相当于只声明了getter方法和同名带下划线的成员变量
但这里同时重写了getter方法,系统就不会自动生成同名带下划线的成员变量,所以使用了@synthesize合成
*/
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
// 获取沙盒
- (NSURL *)applicationDocumentsDirectory {
// The directory the application uses to store the Core Data store file. This code uses a directory named "---ShenYJ---._1_Core_Data" in the application's documents directory.
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
// 获取数据模型文件
- (NSManagedObjectModel *)managedObjectModel {
// The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
// 设置数据模型文件的路径
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"model" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
// 获取持久化协调器
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it.
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
// 生成持久化协调器&数据库
// 创建持久化协调器 需要设置数据模型文件
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
// 设置数据库路径 (自定义路径)
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"model.sqlite"];
// 打印错误
NSError *error = nil;
NSString *failureReason = @"There was an error creating or loading the application's saved data.";
// 持久化协调器 设置持久化类型
/*
NSSQLiteStoreType 数据库
NSXMLStoreType XML文件,相当于plist存储
NSBinaryStoreType 二进制,相当于归档
NSInMemoryStoreType 内存中,相当于缓存
(所以我们一般只使用这种类型)
*/
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// Report any error we got.
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
dict[NSLocalizedFailureReasonErrorKey] = failureReason;
dict[NSUnderlyingErrorKey] = error;
error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
// Replace this 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();
}
return _persistentStoreCoordinator;
}
// 获取数据上下文
- (NSManagedObjectContext *)managedObjectContext {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
// 获取持久化协调器
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (!coordinator) {
return nil;
}
// 创建数据上下文 : 并发类型
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
/**
并发类型: 上下文操作在什么线程执行
* NSPrivateQueueConcurrencyType = 0x01, 在异步线程中执行上细纹操作
NSMainQueueConcurrencyType = 0x02 在主线程中执行上下文操作
*/
// 数据上下文 需要设置 持久化协调器
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
return _managedObjectContext;
// 实际上数据上下文保存数据后,数据库的存储操作都是由持久化协调器来完成
}
#pragma mark - Core Data Saving support
// 保存数据上下文
- (void)saveContext {
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
NSError *error = nil;
// 错误打印&保存上下文 如果上下文发生变化&上下文保存失败 就执行下边的错误打印
if ([managedObjectContext hasChanges] && ![managedObjectContext 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();
}
}
}
@end
如果对数据模型文件路径有要求,可以自己来设置