IOS开发之一:CoreData入门与进阶
CoreData提供了一种简便的对象持久化管理方法,使你可以不用关心数据的存储,只需要关心对象的增加、删除、更改、读写。
并且CoreData提供模型操作方式,可以和UITableView完美的进行结合使用,不用写sql语句,降低出错率.
CoreData核心类:

基本概念
托管对象(managed object)
managed object代表你想要存储的实例化的一个对象。这在概念上类似于SQL中的一条记录, 并且通常也包含一些域,这些域对应于你想要保存的对象的属性。
数据存储(data store)
Core Data支持4中类型的数据存储:SQLiteStore, XMLStore, BinaryStore, InMemoryStore。
1.初始化NSManagedObjectModel对象,加载模型文件,读取app中的所有实体信息
2.初始化NSPersistentStoreCoordinator对象,添加持久化库(这里采取SQLite数据库)
3.初始化NSManagedObjectContext对象,拿到这个上下文对象操作实体,进行CRUD操作
+(instancetype)sharedCoreDataManager { static CoreDataManager *manager; static dispatch_once_t pre; dispatch_once(&pre, ^{ manager = [[CoreDataManager alloc] init]; }); return manager; }
#import <Foundation/Foundation.h> #import <CoreData/CoreData.h> @interface CoreDataManager : NSObject @property(readonly,nonatomic,strong)NSManagedObjectContext *managedObjectContext; @property(readonly,nonatomic,strong)NSManagedObjectModel *managedObjectModel; @property(readonly,nonatomic,strong)NSPersistentStoreCoordinator *persistentStoreCoordinator; +(instancetype)sharedCoreDataManager; @end
紧接着,创建CoreData所需要的文件.xcdatamodeld文件,命名为Person

蓝后,我们打开CoreDataManager.m文件,添加实现代码
//NSManagedObjectModel实际上就是加载xcdatamodeld文件,读取里面的实体等信息 -(NSManagedObjectModel *)managedObjModel { if (_managedObjModel) { return _managedObjModel; } NSURL *url = [[NSBundle mainBundle] URLForResource:@"Person" withExtension:@"momd"];
_managedObjModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:url]; return _managedObjModel; } //持久化存储助理:相当于数据库的连接器 -(NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (_persistentStoreCoordinator) { return _persistentStoreCoordinator; } _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjModel]; // 构建SQLite数据库文件的路径 NSURL *storeUrl = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent:@"Person.sqlite"]; NSString *failureReason = @"There was an error creating or loading the application's saved data."; //添加数据库 NSError *error; NSPersistentStore *store = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]; if (store == nil) { // 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 *)managedObjContext { if (!_managedObjContext) { _managedObjContext = [[NSManagedObjectContext alloc] init]; [_managedObjContext setPersistentStoreCoordinator:self.persistentStoreCoordinator]; } return _managedObjContext; }
接着,我们为CoreDataManager类添加一个保存方法:
- (void)saveContext { NSManagedObjectContext *managedObjectContext = self.managedObjContext; 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(); } } }
至此,我们的数据库操作的类,已经创建完成,可以使用了。
接下来,我们开始简单的使用.我们创建一个tableViewController该控制的右上方有一个有一个+号button。
我们将window的根控制器设置为一个导航控制器,导航控制器的根控制器为一个tableViewController。
1.首先创建实体。该实体有一个name,age,height.

2.我们实现点击+号button添加一条数据,向左滑动cell删除一条数据。点击cell实现修改其名称为changedName,实现简单的增,删,改,查.
我们在viewDidLoad方法里读取本地是否有缓存数据,实现查询数据:
- (void)viewDidLoad { [super viewDidLoad]; //右上角+号按钮 UIButton *rightBtn = [UIButton buttonWithType:UIButtonTypeContactAdd]; self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:rightBtn]; [rightBtn addTarget:self action:@selector(add) forControlEvents:UIControlEventTouchDown]; self.managedCtx = [CoreDataManager sharedCoreDataManager].managedObjContext; //根据实体名称创建一个FetchRequest NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Person"]; //执行查询,该方法是NSManagedObjectContext的对象方法,返回一个数组 NSArray *personArr = [[CoreDataManager sharedCoreDataManager].managedObjContext executeFetchRequest:request error:nil]; _sourceArr = [NSMutableArray arrayWithArray:personArr]; }
当我们点击右上角的+号时我们插入一条数据,并刷新表格
- (void)add { //根据实体创建出一个NSManagedObject对象 NSManagedObject *obj = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedCtx]; NSString *name = [NSString stringWithFormat:@"testName%d",self.index]; NSNumber *height = [NSNumber numberWithDouble:arc4random()]; //设置NSManagedObject对象的值kvc的方式 [obj setValue:height forKey:@"height"]; [obj setValue:name forKey:@"name"]; //保存 [[CoreDataManager sharedCoreDataManager] saveContext]; self.index++; [_sourceArr addObject:obj]; [self.tableView reloadData]; }
点击某一行表格的时候,修改name属性
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { //取出对应的NSManagedObject对象 NSManagedObject *obj = _sourceArr[indexPath.row]; //修改名称 [obj setValue:@"changedName" forKey:@"name"]; //保存 [[CoreDataManager sharedCoreDataManager] saveContext]; [self.tableView reloadData]; }
滑动cell的时候删除一条数据,并刷新表格
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { //首先我们取得查询数组中的所要删除的NSManagedObject对象 NSManagedObject *obj = _sourceArr[indexPath.row]; [_sourceArr removeObjectAtIndex:indexPath.row]; [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; [self.tableView reloadData]; //执行删除操作 [[CoreDataManager sharedCoreDataManager].managedObjContext deleteObject:obj]; //保存 [[CoreDataManager sharedCoreDataManager] saveContext]; } else if (editingStyle == UITableViewCellEditingStyleInsert) { // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view } }
至此,我们实现的CoreData的简单的,插入,删除,修改和查询功能,CoreData的功能强大,可以存储大量数据,并且可以利用
NSFetchedResultsController和tableview进行结合使用,并且可以生成NSManagerObject类和属性,而无需使用KVC的方式进行存储值,降低出错。
下一篇,我们将一起来学习CoreData与tableView的结合使用,和多线程加载大量数据.

浙公网安备 33010602011771号