标签:
就像我一直说的,Core Data是iOS编程,乃至Mac编程中使用持久性数据存储的最佳方式,本质上来说,Core Data使用的就是SQLite,但是通过一系列特性避免了使用SQL的一些列的麻烦,不仅如此,他还能够合理管理内存,反正好处很多,我们推荐使用,下面我们先对比它与其他数据持久化方式的优缺点。
1,它允许按照实体-属性-值模型组织数据,并以XML,二进制文件或SQLite数据文件的格式将其序列化,简单的说就是封装了我们将对象储存的系列化和取出来的反序列化;
2,除了为属性整合KVC和KVO的访问方法外, Core Data还整合了适当的集合访问方法来处理多值关系。
3,Core Data中的managed object扩展了标准的KVC 验证方法,以保证单个的数值在可接受的范围之内,从而使组合的值有意义。
4, 自动支持对象存储在外部数据仓库的功能。
5.Core Data 内置了版本跟踪和乐观锁定(optimistic locking)来支持多用户写入冲突的解决
废话不多说了,使用CoreData的时候要注意线程安全,主要是context不要同时操作一个context,而对于数据管理器内部已经做了线程安全保护。那么下面我们直接来上一份代码,如果觉得麻烦我们可以使用方法一
在创建工程的时候我们直接勾选Use Core Data,这样我们会在appdelegate里面看到如下
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;
@end
.m里面多了这些东西
- (NSURL *)applicationDocumentsDirectory {
// The directory the application uses to store the Core Data store file. This code uses a directory named "lanou3g.zouhao" 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:@"zouhao" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
// The persistent store coordinator for the application. This implementation creates and return 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:@"zouhao.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] init];
[_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();
}
}
}
那么问题来了,我们项目可能是以前的,里面没有添加CoreData,我们是不是在建一个项目,选中Use Core Data 然后将以前项目里面的代码粘贴过来啊。这种做法可选但是不可取,作为一个技术人员,我们得想一个最优解。那么下面第二种方法来了
2,我们手动去创建CoreData里面的一些工具类,我们发现appdelegate.h里面有一个多了三个属性,这就是我们CoreData里面的几个常用对象managerCont
managedObjectContext管理上下文,可以理解为一个零时数据库,managerObjectModel数据模型器,persistentStoreCoordinator数据管理器,再看看appdelegate.m里面都实现了几个对象的Get方法,而且还是懒加载,节省内存。下面我们开始手动创建一个单例,实现数据持久化一些管理对象的创建
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface ManagerContext : NSObject
@property (nonatomic, strong)NSManagedObjectContext *context;
@property (nonatomic, strong)NSManagedObjectModel *model;
@property (nonatomic, strong)NSPersistentStoreCoordinator *persistentS;
+ (instancetype)defaultContext;
@end
#import "ManagerContext.h"
@implementation ManagerContext
+ (instancetype)defaultContext
{
static ManagerContext *manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[ManagerContext alloc] init];
});
return manager;
}
- (NSManagedObjectContext *)context
{
if (_context != nil) {
return _context;
}
_context = [[NSManagedObjectContext alloc] init];
[_context setPersistentStoreCoordinator:self.persistentS];
return _context;
}
- (NSPersistentStoreCoordinator *)persistentS
{
if (_persistentS != nil) {
return _persistentS;
}
_persistentS = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.model];
NSURL *storeURL = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent:@"main"];
NSError *error;
[_persistentS addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]; return _persistentS;
}
- (NSManagedObjectModel *)model
{
if (_model != nil) {
return _model;
}
NSURL *url = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"momd"];
_model = [[NSManagedObjectModel alloc] initWithContentsOfURL:url];
return _model;
}
@end
这样我们是不是实现了勾选Use Core Data时一样的功能。那么重点来了,我们看看用法,如何取值如何存储,这才是大家最关心的是吧,作为一个数据持久化的一种发式,当然重点在于功能啦,那下面开始上代码了
去数据的过程
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"ClassEntity"];
NSError *error;
NSArray *array = [[ManagerContext defaultContext].context executeFetchRequest:request error:&error];
if (!error) {
[self.dataArray setArray:array];
[self.tableView reloadData];
} else {
UIAlertView *alertV = [[UIAlertView alloc] initWithTitle:@"提示" message:@"取数据失败" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
[alertV show];
}
存数据的过程
NSEntityDescription *classED = [NSEntityDescription entityForName:@"ClassEntity" inManagedObjectContext:[ManagerContext defaultContext].context];
ClassEntity *classE = [[ClassEntity alloc] initWithEntity:classED insertIntoManagedObjectContext:[ManagerContext defaultContext].context];
classE.name = @"BJ20";
classE.num = @59;
classE.teacher.name = @"zouhao";
classE.teacher.age = @32;
NSError *error;
[[ManagerContext defaultContext].context save:&error];
if (!error) {
[self.navigationController popViewControllerAnimated:YES ];
} else {
UIAlertView *alertV = [[UIAlertView alloc] initWithTitle:@"提示" message:@"保存信息失败" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
[alertV show];
}
今天就讲到这里了,后期会继续改进,麻烦大家多多支持
标签:
原文地址:http://www.cnblogs.com/zouhaoit/p/4435676.html