2.1 Core Data入门
1.Core Data是什么
Core Data是基于数据模式(schema)的数据管理解决方案,其并不是关系型数据库。它是设计来与MVC设计模式协同工作的。从Core Data取信息时,会创建并返回一个装有managed object的数组。这些对象都是OC实体,是从OC类创建而来的。Core Data关注的是对象,而不是值。
2.Core Data栈
-
受控对象模型(managed object model)
简称对象模型,是一种模式,定义了应用中的数据结构,.xcdatamodeld文件。
Core Data编辑器教程- (NSManagedObjectModel *)managedObjectModel{ if (__managedObjectModel != nil) { return __managedObjectModel; } NSURL *modelURL = [[NSBundle mainBundle] URLForResource:ManagedObjectModelFileNa
me withExtension:@"momd"]; __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; return __managedObjectModel; } -
持久化存储调度器(Persistent Store Coordinator)
managed object和关系会受该调度器的管理if (__persistentStoreCoordinat
or != nil){ return __persistentStoreCoordinat or; } // Set up persistent Store Coordinator __persistentStoreCoordinat or = [[NSPersistentStoreCoordin ator alloc] initWithManagedObjectMod el:[self managedObjectModel]]; -
持久化存储和存储文件(Perisistent Object Store,Store File)
将一个持久化存储直接添加到一个已有的调度器中。//创建数据库文件的URL NSURL *storeURL=[[self applicationDocumentsDire
ctory]URLByAppendPathComponent :@"DemoCoreData.sqlite"]; //创建持久化存储添加到一个已有的调度器 NSError *error = nil; if (![__persistentStoreCoordinat or addPersistentStoreWithTy pe:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]){ //处理错误 NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } //applicationDocumentsDire ctory方法 - (NSURL *)applicationDocumentsDire ctory{ return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; }
支持三种类型的存储
- NSSQliteStoreType
- NSBinaryStoreType
- NSInMemoryStoreType
-
受控对象上下文(Managed Object Context)
管理Core Data创建并返回的对象.- (NSManagedObjectContext *)managedObjectContext{ if (__managedObjectContext != nil){ return __managedObjectContext; } NSPersistentStoreCoordin
ator *coordinator = [self persistentStoreCoordinat or]; if (coordinator != nil){ NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyTy pe]; [moc performBlockAndWait:^(void){ // Set up an undo manager, not included by default,略 // Set persistent store [moc setPersistentStoreCoordi nator:coordinator]; __managedObjectContext = moc; } return __managedObjectContext; } - (NSArray*)notifications{ //1.创建描述对象,设置获取的实体为Notification对象 NSEntityDescription *entity = [NSEntityDescription entityForName:@"Notification" inManagedObjectContext:__managedObjectContext]; //2.创建一个新的获取请求 NSFetchRequest *request = [[NSFetchRequest alloc] init]; [request setEntity:entity]; //3.执行获取请求,获取结果,这里没有谓词,返回所有结果 NSError *error = nil; NSArray *fetchResults = [__managedObjectContext executeFetchRequest:request error:&error]; if (fetchResults == nil) { NSLog(@"Error retrieving Notifications"); return nil; } //4.返回对象集合,这个array里都是Notification对象 if([fetchResults count] > 0) return fetchResults; return nil; } -
补:Core Data中的并发性:
- NSConfinementConcurrency
Type - NSMainQueueConcurrencyTy
pe - NSPrivateQueueConcurrenc
yType
- NSConfinementConcurrency
2.2 在Xcode中设置Core Data
基本步骤
- 创建受控对象模型(managed object model)
- 创建持久化存储调度器(Persistent Store Coordinator)
- 为持久化存储调度器添加持久化对象存储(Perisistent Object Store,Store File)
- 创建受控对象上下文(Managed Object Context)并设置存储调度器
2.3 与Core Data互动
操作一般属于下面四种
-
添加新对象
- (void)addReminder:(UIBarButtonItem*)button{ //1.向上下文插入并且返回一个新的对象 Reminder *newReminder = [sharedModel makeReminderWithTitle:@"New Reminder"]; //2.设置插入的对象属性 [newReminder setBody:@"This is the new Reminder body"]; [newReminder setDate:[NSDate date]]; //3.调用保存上下文,所有修改都会被提交到持久化存储中去 [sharedModel saveContext]; //(4.保存完成之后的一些操作,如更新界面等) [self persistentStoreDidChange
]; } - (Reminder*)makeReminderWithTitle:(NSString *)title{ //1.向上下文插入并且返回一个新的对象 Reminder *newReminder = (Reminder*)[NSEntityDescription insertNewObjectForEntity ForName:@"Reminder" inManagedObjectContext:__managedObjectContext]; //2.设置插入的对象属性 [newReminder setTitle:title]; return newReminder; } - (BOOL)saveContext{ NSError *error = nil; NSManagedObjectContext *managedObjectContext = self.managedObjectContext; if (managedObjectContext != nil){ if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]){ NSLog(@"Unresolved error %@, %@", error, [error userInfo]); return NO; } } else{ NSLog(@"Managed Object Context is nil"); return NO; } NSLog(@"Context Saved, iCloud should sync if enabled"); return YES; } -
获取对象并修改数据
//1.创建一个获取请求,并将获取请求的实体设置为Reminder对象 NSFetchRequest *request = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Reminder" inManagedObjectContext:__managedObjectContext]; [request setEntity:entity]; //2.创建谓词predicate来限定请求结果,还可以设置获取结果的排序方法 NSPredicate *query = [NSPredicate predicateWithFormat:@"title == %@",title]; [request setPredicate:query]; //设置获取结果的排序方法Set up the request sorting NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:YES]; [request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; //3.执行请求,获取结果 NSError *error = nil; NSArray *fetchResults = [__managedObjectContext executeFetchRequest:request error:&error]; //4.如果得到结果,修改它的属性 if([fetchResults count] > 0){ Reminder *reminder=(Reminder*)[fetchResults objectAtIndext:0]; reminder.body=@"newbody"; } //5.调用保存上下文,所有修改都会被提交到持久化存储中去 [self saveContext];//代码见上.
-
删除对象
//步骤1.2.3同上略 //步骤4.删除结果 for(Reminder *reminder in fetchResults){ [__managedObjectContext deleteObject:reminder]; } //5.调用保存上下文,所有修改都会被提交到持久化存储中去 return [self saveContext];
-
撤销、重做、回滚、复位
注意撤销操作管理器纪录的事用户操作事件,如果是通过程序的操作是不会纪录这些改动的//1.在创建managedObjectContext的时候设置undoManager,见2.1中的managedObjectContext NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyTy
pe]; [moc performBlockAndWait:^(void){ // Set up an undo manager, not included by default NSUndoManager *undoManager = [[NSUndoManager alloc] init]; [undoManager setGroupsByEvent:NO]; [moc setUndoManager:undoManager]; // Set persistent store [moc setPersistentStoreCoordi nator:coordinator]; //icloud略 } }]; - (void)undo{ [__managedObjectContext undo]; } - (void)redo{ [__managedObjectContext redo]; } - (void)rollback{ [__managedObjectContext rollback]; } - (void)reset{ [__managedObjectContext reset]; }