码迷,mamicode.com
首页 > 其他好文 > 详细

CoreData详解与使用

时间:2015-04-17 20:16:05      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:

iOS教程:Core Data数据持久性存储详解

就像我一直说的,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];

 

    }

 今天就讲到这里了,后期会继续改进,麻烦大家多多支持

 

CoreData详解与使用

标签:

原文地址:http://www.cnblogs.com/zouhaoit/p/4435676.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!