概述
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类或者其子类的实例。托管对象模型包含一些应用程序托管对象实体的描述,描述中包括属性,关系等。
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;
@property (nonatomic, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (nonatomic, readonly) NSManagedObjectContext *managedObjectContext;
- (NSURL *)dataStoreURL;
- (Car *)makeNewCar;
- (NSArray *)carListAfterFetch;
返回数据存储的URL函数
- - (NSURL *)dataStoreURL
- {
- static NSString *fileName = @"Car.sql";
- NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
- NSString *filePath = [docDir stringByAppendingPathComponent:fileName];
- NSURL *fileURL = [NSURL fileURLWithPath:filePath];
- return fileURL;
- }
数据模型NSManagedObjectModel
- - (NSManagedObjectModel *)managedObjectModel
- {
- if (_managedObjectModel)
- {
- return _managedObjectModel;
- }
- _managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
- return _managedObjectModel;
- }
使用持久化存储协调器,链接到数据模型
- - (NSPersistentStoreCoordinator *)persistentStoreCoordinator
- {
- if (_persistentStoreCoordinator)
- {
- return _persistentStoreCoordinator;
- }
- _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
- NSError *error;
- if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
- configuration:nil
- URL:[self dataStoreURL]
- options:nil
- error:&error])
- {
- NSLog(@"Error: %@", error);
- }
- return _persistentStoreCoordinator;
- }
建立托管对象上下文,记录对象图的所有变化。在一些时候,可以执行抓取数据信息并进行检索等等。
- - (NSManagedObjectContext *)managedObjectContext
- {
- if (_managedObjectContext)
- {
- return _managedObjectContext;
- }
- _managedObjectContext = [[NSManagedObjectContext alloc] init];
- [_managedObjectContext setPersistentStoreCoordinator:[self persistentStoreCoordinator]];
- return _managedObjectContext;
- }
一个创建汽车实例的方法
- - (Car *)makeNewCar
- {
- Car *newCar = [NSEntityDescription insertNewObjectForEntityForName:@"Car"
- inManagedObjectContext:[self managedObjectContext]];
- return newCar;
- }
检索数据方法,返回一个数组储存目前存在的实例的信息
- - (NSArray *)carListAfterFetch
- {
- NSError *error;
- NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
- NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:[self managedObjectContext]];
- fetchRequest.entity = entity;
- NSArray *listOfCars = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
- return listOfCars;
- }
测试
在APPDelegate.m里对主要的方法进行了简单的使用
- CarModel *carModel = [[CarModel alloc] init];
- NSManagedObjectContext *carContext = [carModel managedObjectContext];
- Car *car1 = [carModel makeNewCar];
- car1.brand = @"BMW";
- car1.type = @"SUV";
- [carContext save:nil];
- NSArray *listOfCars = [carModel carListAfterFetch];
- [listOfCars enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
- NSLog(@"CarInList[%i] : %@", idx, [obj brand]);
- }];
- Car *rollbackCar = [listOfCars objectAtIndex:0];
- rollbackCar.brand = @"AUDI";
- if ([carContext hasChanges]) {
- [carContext rollback];
- }
- listOfCars = [carModel carListAfterFetch];
- [listOfCars enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
- NSLog(@"CarInList[%i] : %@", idx, [obj brand]);
- }];
- [carContext deleteObject:car1];
- [carContext save:nil];
- listOfCars = [carModel carListAfterFetch];
- if ([listOfCars count] == 0) {
- NSLog(@"NULL");
- }
- else {
- [listOfCars enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
- NSLog(@"CarInList[%i] : %@", idx, [obj brand]);
- }];
- }
打印的结果是
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
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。
CoreData不光能操纵SQLite,CoreData和iCloud的结合也很好,如果有这方面需求的话优先考虑CoreData。
提供NSFetchedResultsController 类用于管理表视图的数据。即将Core Data的持久化存储显示在表视图中,并对这些数据进行管理:增、删,改。
管理undo/redo操作。
检查托管对象的属性值是否正确。
管理undo/redo操作。
检查托管对象的属性值是否正确。
虽然现在还不能直接设置主键,但是其已经足够强大,也相信以后将会更加便捷。