CoreData
CoreData是苹果系统提供的一套数据本地存储API,提供了一个强大的近自动化的存储方式,我们不用关心内部怎么存储,怎么删除,怎么查找,只需要提供存储路径,存储方式,执行增删改查的命令就行了,那CoreData是怎么做到这些的呢?
API提供了几个相关类,也就是CoreData的核心框架Core Data Stack,有NSManagedObjectContext、NSPersistentStoreCoordinate和NSManagedObjectModel:
NSManagedObjectContext 是CoreData存储管理上下文,负责整个app的数据操作;
NSPersistentStoreCoordinate负责NSManagedObjectModel的存储,定义了存储数据的方式,路径及存储策略;
NSManagedObjectModel被管理的对象模型,就是我们创建coreData生成的.xcdatamodel文件;
下面通过这三个重要类的定义,我们详细的看看其作用,首先_managedObjectModel定义了app内要操作的coredata文件是yingshibao.momd,其实就是.xcdatamodel文件,_persistentStoreCoordinator定义了存储的文件类型是NSSQLiteStoreType数据库,其次指定了存储的model是_managedObjectModel,这就把app内和沙盒联系起来了,最后一个就是NSManagedObjectContext,对数据的操作就通过传入的NSManagedObjectContext参数来确定操纵的是哪一个存储上下文
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"yingshibao.sqlite"];
NSError *error = nil;
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"yingshibao" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: _managedObjectModel];
NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption : [NSNumber numberWithBool:YES],
NSInferMappingModelAutomaticallyOption : [NSNumber numberWithBool:YES]};
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
NSAssert(0, @"数据库表结构有变化,删除重新测试");
}
if (coordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
下方图中解释了这三者之间的工作关系
20160711190941786.jpeg
通常一个项目里我们只使用一个数据库就搞定本地持久化了, 而实际项目中,有时候需要将不同业务的数据存储在不同的沙盒位置,这时候我们可以通过创建多个context上下文,去对应多个沙盒位置,但是用同一个NSPersistentStoreCoordinator就可以,因为NSPersistentStoreCoordinator可以添加多个NSPersistentStore来负责NSManagedObjectModel的存储,
//每执行一次这个代码就为_persistentStoreCoordinator添加一个NSPersistentStore,每个NSPersistentStore对应一种存储(一个存储路径和一种存储文件类型)
[_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]
20160711191002361.jpeg
使用
增:每一个data model对应一个NSEntityDescription对象,NSEntityDescription对象包含了Entity所拥有的属性,关系等信息,我们可以通过NSEntityDescription生成相应的NSManagedObject的实体
Student *student = [NSEntityDescription insertNewObjectForEntityForName:@"Student" inManagedObjectContext:context];
student.name = @"李四";
[context save];
查:NSFetchRequest负责查询,可以定义查询条件和结果排序规则
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@","李四"];
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
[request setPredicate:predicate];
[request setSortDescriptors:@[sort]];
NSArray *result = [context executeFetchRequest:request error:nil];
删: 删的前提是查找,继查找之后
for (Student *stu in result) {
[context deleteObject:stu];
}
//别忘记保存
[context save:nil];
改: 改的前提也是查找,继查找之后
stu.name = @"张三";
//别忘记保存
[context save:nil];
另外一个简便的获取展示的列表数据的类NSFetchedResultsController,初始化的过程就是查询的过程,通过这个类可以直接访问查询结果,包括列表分区展示等
NSFetchedResultsController *vc = [[NSFetchedResultsController alloc]initWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:@"以哪个字段分区展示如 age" cacheName:nil];
//获取分区信息
vc.sections
NSFetchedResultsSectionInfo *sectionInfo = vc.sections[0];
sectionInfo.name
//数据
vc.fetchedObjects
[vc objectAtIndexPath:indexPath];
网友评论