iOS App中數(shù)據(jù)管理框架Core Data的基本數(shù)據(jù)操作教程
NSEntityDescription是實(shí)體描述對(duì)象,它可以類比如數(shù)據(jù)庫(kù)中的表,NSEntityDescription存放的是表的結(jié)構(gòu)信息。這些類都是一些抽象的結(jié)構(gòu)類,并不存儲(chǔ)實(shí)際每條數(shù)據(jù)的信息,具體的數(shù)據(jù)由NSManagedObject類來(lái)描述,我們一般會(huì)將實(shí)體類化繼承于NSManagedObject。
Xocde工具提供了快捷的實(shí)體類化功能,還拿我們一開始創(chuàng)建的班級(jí)與學(xué)生實(shí)體來(lái)演示,點(diǎn)擊.xcdatamodeld文件,點(diǎn)擊Xcode工具上方導(dǎo)航欄的Editor標(biāo)簽,選擇Creat NSManagedObject Subclass選項(xiàng),在彈出的窗口中勾選要類化的實(shí)體,如下圖:
這時(shí),Xcode會(huì)自動(dòng)為我們創(chuàng)建一個(gè)文件,這些文件中有各個(gè)類中屬性的聲明。
一、創(chuàng)建一條數(shù)據(jù)
使用如下代碼進(jìn)行數(shù)據(jù)的創(chuàng)建:
//讀取數(shù)據(jù)模型文件
找到在打印出的路徑,會(huì)發(fā)現(xiàn)里面多了一個(gè)sqlite文件,其中有一張表中添加進(jìn)了一條數(shù)據(jù)。
NSURL *modelUrl = [[NSBundle mainBundle]URLForResource:@"Model" withExtension:@"momd"];
//創(chuàng)建數(shù)據(jù)模型
NSManagedObjectModel * mom = [[NSManagedObjectModel alloc]initWithContentsOfURL:modelUrl];
//創(chuàng)建持久化存儲(chǔ)協(xié)調(diào)者
NSPersistentStoreCoordinator * psc = [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:mom];
//數(shù)據(jù)庫(kù)保存路徑
NSURL * path =[NSURL fileURLWithPath:[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"CoreDataExample.sqlite"]];
//為持久化協(xié)調(diào)者添加一個(gè)數(shù)據(jù)接收棧
/*
可以支持的類型如下:
NSString * const NSSQLiteStoreType;//sqlite
NSString * const NSXMLStoreType;//XML
NSString * const NSBinaryStoreType;//二進(jìn)制
NSString * const NSInMemoryStoreType;//內(nèi)存
*/
[psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:path options:nil error:nil];
//創(chuàng)建數(shù)據(jù)管理上下文
NSManagedObjectContext * moc = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType];
//關(guān)聯(lián)持久化協(xié)調(diào)者
[moc setPersistentStoreCoordinator:psc];
//創(chuàng)建數(shù)據(jù)對(duì)象
/*
數(shù)據(jù)對(duì)象的創(chuàng)建是通過(guò)實(shí)體名獲取到的
*/
SchoolClass * modelS = [NSEntityDescription insertNewObjectForEntityForName:@"SchoolClass" inManagedObjectContext:moc];
//對(duì)數(shù)據(jù)進(jìn)行設(shè)置
modelS.name = @"第一班";
modelS.stuNum = @60;
//進(jìn)行存儲(chǔ)
if ([moc save:nil]) {
NSLog(@"新增成功");
}
NSLog(@"%@",[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"CoreDataExample.sqlite"]);
二、查詢數(shù)據(jù)
CoreData中通過(guò)查詢請(qǐng)求來(lái)對(duì)數(shù)據(jù)進(jìn)行查詢操作,查詢請(qǐng)求由NSFetchRequest來(lái)進(jìn)行管理和維護(hù)。
NSFetchRequest主要提供兩個(gè)方面的查詢服務(wù):
1.提供范圍查詢的相關(guān)功能
2.提供查詢結(jié)果返回類型與排序的相關(guān)功能
NSFetchRequest中常用方法如下:
//創(chuàng)建一個(gè)實(shí)體的查詢請(qǐng)求 可以理解為在某個(gè)表中進(jìn)行查詢
+ (instancetype)fetchRequestWithEntityName:(NSString*)entityName;
//查詢條件
@property (nullable, nonatomic, strong) NSPredicate *predicate;
//數(shù)據(jù)排序
@property (nullable, nonatomic, strong) NSArray<NSSortDescriptor *> *sortDescriptors;
//每次查詢返回的數(shù)據(jù)條數(shù)
@property (nonatomic) NSUInteger fetchLimit;
//設(shè)置查詢到數(shù)據(jù)的返回類型
/*
typedef NS_OPTIONS(NSUInteger, NSFetchRequestResultType) {
NSManagedObjectResultType = 0x00,
NSManagedObjectIDResultType = 0x01,
NSDictionaryResultType NS_ENUM_AVAILABLE(10_6,3_0) = 0x02,
NSCountResultType NS_ENUM_AVAILABLE(10_6,3_0) = 0x04
};
*/
@property (nonatomic) NSFetchRequestResultType resultType;
//設(shè)置查詢結(jié)果是否包含子實(shí)體
@property (nonatomic) BOOL includesSubentities;
//設(shè)置要查詢的屬性值
@property (nullable, nonatomic, copy) NSArray *propertiesToFetch;
在SchoolClass實(shí)體中查詢數(shù)據(jù),使用如下的代碼:
//創(chuàng)建一條查詢請(qǐng)求
NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"SchoolClass"];
//設(shè)置條件為 stuNum=60的數(shù)據(jù)
[request setPredicate:[NSPredicate predicateWithFormat:@"stuNum == 60"]];
//進(jìn)行查詢操作
NSArray * res = [moc executeFetchRequest:request error:nil];
NSLog(@"%@",[res.firstObject stuNum]);
進(jìn)行數(shù)據(jù)初始化
NSFetchedResultsController的初始化需要一個(gè)查詢請(qǐng)求和一個(gè)數(shù)據(jù)操作上下文。代碼示例如下:
//遵守協(xié)議
@interface ViewController ()<NSFetchedResultsControllerDelegate>
{
//數(shù)據(jù)橋接對(duì)象
NSFetchedResultsController * _fecCon;
}
@end
@implementation ViewController
- (void)viewDidLoad {
用于初始化NSFecthedResultsController的數(shù)據(jù)請(qǐng)求對(duì)象必須設(shè)置一個(gè)排序規(guī)則。在initWithFetchRequest:managedObjectContext:sectionNameKeyPath:cacheName:方法中,如果設(shè)置第三個(gè)參數(shù),則會(huì)以第三個(gè)參數(shù)為鍵值進(jìn)行數(shù)據(jù)的分區(qū)。當(dāng)數(shù)據(jù)發(fā)生變化時(shí),將通過(guò)代理進(jìn)行方法的回調(diào)。
[super viewDidLoad];
//進(jìn)行初始化操作
NSURL *modelUrl = [[NSBundle mainBundle]URLForResource:@"Model" withExtension:@"momd"];
NSManagedObjectModel * mom = [[NSManagedObjectModel alloc]initWithContentsOfURL:modelUrl];
NSPersistentStoreCoordinator * psc = [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:mom];
NSURL * path =[NSURL fileURLWithPath:[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"CoreDataExample.sqlite"]];
[psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:path options:nil error:nil];
NSManagedObjectContext * moc = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType];
[moc setPersistentStoreCoordinator:psc];
NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"SchoolClass"];
//設(shè)置數(shù)據(jù)排序
[request setSortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"stuNum" ascending:YES]]];
//進(jìn)行數(shù)據(jù)橋接對(duì)象的初始化
_fecCon = [[NSFetchedResultsController alloc]initWithFetchRequest:request managedObjectContext:moc sectionNameKeyPath:nil cacheName:nil];
//設(shè)置代理
_fecCon.delegate=self;
//進(jìn)行數(shù)據(jù)查詢
[_fecCon performFetch:nil];
}
@end
三、與UITableView進(jìn)行數(shù)據(jù)綁定
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
效果如下:
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cellid"];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cellid"];
}
//獲取相應(yīng)數(shù)據(jù)模型
SchoolClass * obj = [_fecCon objectAtIndexPath:indexPath];
cell.textLabel.text = obj.name;
cell.detailTextLabel.text = [NSString stringWithFormat:@"有%@人",obj.stuNum];
return cell;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return [_fecCon sections].count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
id<NSFetchedResultsSectionInfo> info = [_fecCon sections][section];
return [info numberOfObjects];
}
四、將數(shù)據(jù)變化映射到視圖
//數(shù)據(jù)將要改變時(shí)調(diào)用的方法
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
//開啟tableView更新預(yù)處理
[[self tableView] beginUpdates];
}
//分區(qū)數(shù)據(jù)改變時(shí)調(diào)用的方法
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
//判斷行為類型
switch(type) {
//插入新分區(qū)
case NSFetchedResultsChangeInsert:
[[self tableView] insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
//刪除分區(qū)
case NSFetchedResultsChangeDelete:
[[self tableView] deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
//移動(dòng)分區(qū)
case NSFetchedResultsChangeMove:
//更新分區(qū)
case NSFetchedResultsChangeUpdate:
break;
}
}
//數(shù)據(jù)改變時(shí)回調(diào)的代理
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
switch(type) {
//插入數(shù)據(jù)
case NSFetchedResultsChangeInsert:
[[self tableView] insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
//刪除數(shù)據(jù)
case NSFetchedResultsChangeDelete:
[[self tableView] deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
//更新數(shù)據(jù)
case NSFetchedResultsChangeUpdate:
[self reloadData];
break;
//移動(dòng)數(shù)據(jù)
case NSFetchedResultsChangeMove:
[[self tableView] deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[[self tableView] insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
//數(shù)據(jù)更新結(jié)束調(diào)用的代理
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[[self tableView] endUpdates];
}
相關(guān)文章
iOS微信分享后關(guān)閉發(fā)送成功提示并返回應(yīng)用
這篇文章主要為大家詳細(xì)介紹了iOS微信分享后關(guān)閉發(fā)送成功提示并返回應(yīng)用的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09iOS App開發(fā)中導(dǎo)航欄的創(chuàng)建及基本屬性設(shè)置教程
這篇文章主要介紹了iOS App開發(fā)中導(dǎo)航欄的創(chuàng)建及基本屬性設(shè)置教程,即用UINavigationController來(lái)編寫navigation,示例代碼為Objective-C語(yǔ)言,需要的朋友可以參考下2016-02-02Objective-C中關(guān)于實(shí)例所占內(nèi)存的大小詳解
這篇文章主要給大家介紹了關(guān)于Objective-C中實(shí)例所占內(nèi)存的大小的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)各位iOS開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05簡(jiǎn)述iOS屬性中的內(nèi)存管理參數(shù)
這篇文章主要介紹了簡(jiǎn)述iOS屬性中的內(nèi)存管理參數(shù) 的相關(guān)資料,需要的朋友可以參考下2018-02-02淺談Unity中IOS Build Settings選項(xiàng)的作用
下面小編就為大家分享一篇淺談Unity中IOS Build Settings選項(xiàng)的作用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01IOS使用NSUserDefault去實(shí)現(xiàn)界面?zhèn)髦岛蛿?shù)據(jù)存儲(chǔ)
這篇文章主要介紹了IOS使用NSUserDefault去實(shí)現(xiàn)界面?zhèn)髦岛蛿?shù)據(jù)存儲(chǔ)的相關(guān)資料,需要的朋友可以參考下2017-07-07iOS 11 UINavigationItem 去除左右間隙的方法
本篇文章主要介紹了iOS 11 UINavigationItem 去除左右間隙的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10Xcode 10升級(jí)導(dǎo)致項(xiàng)目報(bào)錯(cuò)的常見問(wèn)題解決
這篇文章主要給大家介紹了關(guān)于Xcode 10升級(jí)導(dǎo)致項(xiàng)目報(bào)錯(cuò)的常見問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-12-12關(guān)于iOS導(dǎo)航欄返回按鈕問(wèn)題的解決方法
這篇文章主要為大家詳細(xì)介紹了關(guān)于iOS導(dǎo)航欄返回按鈕問(wèn)題的解決方法,對(duì)iOS自定義backBarButtonItem的點(diǎn)擊事件進(jìn)行介紹,感興趣的小伙伴們可以參考一下2016-05-05