CoreData
CoreData是蘋果系統(tǒng)提供的一套數(shù)據(jù)本地存儲API而姐,提供了一個(gè)強(qiáng)大的近自動化的存儲方式,我們不用關(guān)心內(nèi)部怎么存儲划咐,怎么刪除拴念,怎么查找,只需要提供存儲路徑褐缠,存儲方式政鼠,執(zhí)行增刪改查的命令就行了,那CoreData是怎么做到這些的呢队魏?
API提供了幾個(gè)相關(guān)類公般,也就是CoreData的核心框架Core Data Stack,有NSManagedObjectContext胡桨、NSPersistentStoreCoordinate和NSManagedObjectModel:
NSManagedObjectContext 是CoreData存儲管理上下文官帘,負(fù)責(zé)整個(gè)app的數(shù)據(jù)操作;
NSPersistentStoreCoordinate負(fù)責(zé)NSManagedObjectModel的存儲昧谊,定義了存儲數(shù)據(jù)的方式刽虹,路徑及存儲策略;
NSManagedObjectModel被管理的對象模型呢诬,就是我們創(chuàng)建coreData生成的.xcdatamodel文件涌哲;
下面通過這三個(gè)重要類的定義胖缤,我們詳細(xì)的看看其作用,首先_managedObjectModel定義了app內(nèi)要操作的coredata文件是yingshibao.momd,其實(shí)就是.xcdatamodel文件阀圾,_persistentStoreCoordinator定義了存儲的文件類型是NSSQLiteStoreType數(shù)據(jù)庫草姻,其次指定了存儲的model是_managedObjectModel,這就把a(bǔ)pp內(nèi)和沙盒聯(lián)系起來了稍刀,最后一個(gè)就是NSManagedObjectContext,對數(shù)據(jù)的操作就通過傳入的NSManagedObjectContext參數(shù)來確定操縱的是哪一個(gè)存儲上下文
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, @"數(shù)據(jù)庫表結(jié)構(gòu)有變化敞曹,刪除重新測試");
}
if (coordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
下方圖中解釋了這三者之間的工作關(guān)系
通常一個(gè)項(xiàng)目里我們只使用一個(gè)數(shù)據(jù)庫就搞定本地持久化了账月, 而實(shí)際項(xiàng)目中,有時(shí)候需要將不同業(yè)務(wù)的數(shù)據(jù)存儲在不同的沙盒位置澳迫,這時(shí)候我們可以通過創(chuàng)建多個(gè)context上下文局齿,去對應(yīng)多個(gè)沙盒位置,但是用同一個(gè)NSPersistentStoreCoordinator就可以橄登,因?yàn)镹SPersistentStoreCoordinator可以添加多個(gè)NSPersistentStore來負(fù)責(zé)NSManagedObjectModel的存儲抓歼,
//每執(zhí)行一次這個(gè)代碼就為_persistentStoreCoordinator添加一個(gè)NSPersistentStore,每個(gè)NSPersistentStore對應(yīng)一種存儲(一個(gè)存儲路徑和一種存儲文件類型)
[_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]
使用
增:每一個(gè)data model對應(yīng)一個(gè)NSEntityDescription對象拢锹,NSEntityDescription對象包含了Entity所擁有的屬性谣妻,關(guān)系等信息,我們可以通過NSEntityDescription生成相應(yīng)的NSManagedObject的實(shí)體
Student *student = [NSEntityDescription insertNewObjectForEntityForName:@"Student" inManagedObjectContext:context];
student.name = @"李四";
[context save];
查:NSFetchRequest負(fù)責(zé)查詢卒稳,可以定義查詢條件和結(jié)果排序規(guī)則
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];
另外一個(gè)簡便的獲取展示的列表數(shù)據(jù)的類NSFetchedResultsController充坑,初始化的過程就是查詢的過程减江,通過這個(gè)類可以直接訪問查詢結(jié)果,包括列表分區(qū)展示等
NSFetchedResultsController *vc = [[NSFetchedResultsController alloc]initWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:@"以哪個(gè)字段分區(qū)展示如 age" cacheName:nil];
//獲取分區(qū)信息
vc.sections
NSFetchedResultsSectionInfo *sectionInfo = vc.sections[0];
sectionInfo.name
//數(shù)據(jù)
vc.fetchedObjects
[vc objectAtIndexPath:indexPath];