iOS中CoreData資料管理系列四——進行資料與頁面的綁定
一、引言
在上一篇部落格中,我們讨論了CoreData架構中添加與查詢資料的操作,事實上,在大多數情況下,這些資料都是由一個UITableView表視圖進行展示的,是以,CoreData架構中還未開發者提供了一個類NSFetchedResultsController,這個類作為橋接,将視圖與資料進行綁定。
添加與查詢資料操作:
http://my.oschina.net/u/2340880/blog/611430。
二、進行資料初始化
NSFetchedResultsController的初始化需要一個查詢請求和一個資料操作上下文。代碼示例如下:
//遵守協定
@interface ViewController ()<NSFetchedResultsControllerDelegate>
{
//資料橋接對象
NSFetchedResultsController * _fecCon;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//進行初始化操作
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"];
//設定資料排序
[request setSortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"stuNum" ascending:YES]]];
//進行資料橋接對象的初始化
_fecCon = [[NSFetchedResultsController alloc]initWithFetchRequest:request managedObjectContext:moc sectionNameKeyPath:nil cacheName:nil];
//設定代理
_fecCon.delegate=self;
//進行資料查詢
[_fecCon performFetch:nil];
用于初始化NSFecthedResultsController的資料請求對象必須設定一個排序規則。在initWithFetchRequest:managedObjectContext:sectionNameKeyPath:cacheName:方法中,如果設定第三個參數,則會以第三個參數為鍵值進行資料的分區。當資料發生變化時,将通過代理進行方法的回調。
三、與UITableView進行資料綁定
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cellid"];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cellid"];
}
//擷取相應資料模型
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];
效果如下:

四、将資料變化映射到視圖
//資料将要改變時調用的方法
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
//開啟tableView更新預處理
[[self tableView] beginUpdates];
//分區資料改變時調用的方法
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
//判斷行為類型
switch(type) {
//插入新分區
case NSFetchedResultsChangeInsert:
[[self tableView] insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
//删除分區
case NSFetchedResultsChangeDelete:
[[self tableView] deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
//移動分區
case NSFetchedResultsChangeMove:
//更新分區
case NSFetchedResultsChangeUpdate:
//資料改變時回調的代理
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
//插入資料
[[self tableView] insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
//删除資料
[[self tableView] deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
//更新資料
[self reloadData];
//移動資料
//資料更新結束調用的代理
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
[[self tableView] endUpdates];