iOS 数据持久化五-Core Data

概述


Core Data是一种用来解决应用中数据持久化问题的技术。作为一个Cocoa框架,首次在Mac OS X 10.4 Tiger与iOS 3.0系统中出现。它允许按照实体-属性-值模型组织数据,并以XML,二进制文件或SQLite数据文件的格式将其串行化。Core Data允许用户使用代表实体和实体间关系的高层对象来操作数据。它也可以管理串行化的数据,提供对象生存期管理与object graph管理,包括存储。Core Data直接与SQLite交互,避免开发者使用原本的SQL语句。
CoreData的核心概念是托管对象。托管对象是由Core Data管理的简单模型对象,但必须是NSManagedObject类或者其子类的实例。托管对象模型包含一些应用程序托管对象实体的描述,描述中包括属性,关系等。

Core Data中常用的类




Core Data 的初步建立

首先导入框架


创建模型编辑器


这里我想建立三个实体,分别是Car,User和Dealer 在创建好实体后再分别添加属性


高亮选择后可以自动创建对应的类文件


然后我们可以从Style模式里看到我们建立的实体的ER图


建立模型对象类

为了方便管理和使用模型对象,我把有关方法统一建立在了CarModel类中

后面涉及到的主要有:
@property (nonatomic, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (nonatomic, readonly) NSManagedObjectContext *managedObjectContext;

- (NSURL *)dataStoreURL;
- (Car *)makeNewCar;
- (NSArray *)carListAfterFetch;

返回数据存储的URL函数

[cpp]  view plain copy
  1. - (NSURL *)dataStoreURL  
  2. {  
  3.     static NSString *fileName = @"Car.sql";  
  4.     NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];      
  5.     NSString *filePath = [docDir stringByAppendingPathComponent:fileName];  
  6.     NSURL *fileURL = [NSURL fileURLWithPath:filePath];  
  7.       
  8.     return fileURL;  
  9. }  


数据模型NSManagedObjectModel


[cpp]  view plain copy
  1. - (NSManagedObjectModel *)managedObjectModel  
  2. {  
  3.     if (_managedObjectModel)  
  4.     {  
  5.         return _managedObjectModel;  
  6.     }  
  7.     _managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];  
  8.       
  9.     return _managedObjectModel;  
  10. }  

使用持久化存储协调器,链接到数据模型


[cpp]  view plain copy
  1. - (NSPersistentStoreCoordinator *)persistentStoreCoordinator  
  2. {  
  3.     if (_persistentStoreCoordinator)  
  4.     {  
  5.         return _persistentStoreCoordinator;  
  6.     }  
  7.     _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];  
  8.     NSError *error;  
  9.     if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType  
  10.                                                    configuration:nil  
  11.                                                              URL:[self dataStoreURL]  
  12.                                                          options:nil  
  13.                                                            error:&error])  
  14.     {  
  15.         NSLog(@"Error: %@", error);  
  16.     }  
  17.       
  18.     return _persistentStoreCoordinator;  
  19. }  


建立托管对象上下文,记录对象图的所有变化。在一些时候,可以执行抓取数据信息并进行检索等等。


[cpp]  view plain copy
  1. - (NSManagedObjectContext *)managedObjectContext  
  2. {  
  3.     if (_managedObjectContext)  
  4.     {  
  5.         return _managedObjectContext;  
  6.     }  
  7.     _managedObjectContext = [[NSManagedObjectContext alloc] init];  
  8.     [_managedObjectContext setPersistentStoreCoordinator:[self persistentStoreCoordinator]];  
  9.     return _managedObjectContext;  
  10. }  


一个创建汽车实例的方法


[cpp]  view plain copy
  1. - (Car *)makeNewCar  
  2. {  
  3.     Car *newCar = [NSEntityDescription insertNewObjectForEntityForName:@"Car"  
  4.                                                 inManagedObjectContext:[self managedObjectContext]];  
  5.     return newCar;  
  6. }  


检索数据方法,返回一个数组储存目前存在的实例的信息


[cpp]  view plain copy
  1. - (NSArray *)carListAfterFetch  
  2. {  
  3.     NSError *error;  
  4.     NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];  
  5.     NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:[self managedObjectContext]];  
  6.     fetchRequest.entity = entity;  
  7.       
  8.     NSArray *listOfCars = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];  
  9.       
  10.     return listOfCars;  
  11. }  

测试

在APPDelegate.m里对主要的方法进行了简单的使用

[cpp]  view plain copy
  1. CarModel *carModel = [[CarModel alloc] init];  
  2. NSManagedObjectContext *carContext = [carModel managedObjectContext];  
  3.   
  4. Car *car1 = [carModel makeNewCar];  
  5. car1.brand = @"BMW";  
  6. car1.type = @"SUV";  
  7.   
  8. [carContext save:nil];  
  9.   
  10. NSArray *listOfCars = [carModel carListAfterFetch];  
  11.   
  12. [listOfCars enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {  
  13.     NSLog(@"CarInList[%i] : %@", idx, [obj brand]);  
  14. }];  
  15.   
  16. Car *rollbackCar = [listOfCars objectAtIndex:0];  
  17. rollbackCar.brand = @"AUDI";  
  18.   
  19. if ([carContext hasChanges]) {  
  20.     [carContext rollback];  
  21. }  
  22.   
  23. listOfCars = [carModel carListAfterFetch];  
  24.   
  25. [listOfCars enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {  
  26.     NSLog(@"CarInList[%i] : %@", idx, [obj brand]);  
  27. }];  
  28.   
  29. [carContext deleteObject:car1];  
  30. [carContext save:nil];  
  31.   
  32. listOfCars = [carModel carListAfterFetch];  
  33.   
  34. if ([listOfCars count] == 0) {  
  35.     NSLog(@"NULL");  
  36. }  
  37. else {  
  38.     [listOfCars enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {  
  39.         NSLog(@"CarInList[%i] : %@", idx, [obj brand]);  
  40.     }];  
  41. }  

打印的结果是
2013-08-01 21:46:14.860 CoreDataTest[721:c07] CarInList[0] : BMW
2013-08-01 21:46:14.862 CoreDataTest[721:c07] CarInList[0] : BMW
2013-08-01 21:46:14.864 CoreDataTest[721:c07] NULL

这里使用了上下文的存储 删除 读取 回文(rollback)方法
Core Data中还有好多高级方法,如redo/undo等(重做,撤销)。

总结


Core Data看起来比使用SQL语句操作数据更快捷和对象化。但是也有很多喜欢写SQL语句的工程师,更偏爱直接操纵数据库。
总结起来Core Data的优点还是很多:
App升级之后数据库字段或者表有更改会导致crash,CoreData的版本管理和数据迁移变得非常有用,手动写sql语句操作还是麻烦一些。
CoreData不光能操纵SQLite,CoreData和iCloud的结合也很好,如果有这方面需求的话优先考虑CoreData。
提供NSFetchedResultsController 类用于管理表视图的数据。即将Core Data的持久化存储显示在表视图中,并对这些数据进行管理:增、删,改。
管理undo/redo操作。
检查托管对象的属性值是否正确。

虽然现在还不能直接设置主键,但是其已经足够强大,也相信以后将会更加便捷。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值