}
}
}
上面是UITableView的代理方法,代理方法中嵌套了FRC的數(shù)據(jù)獲取代碼,這樣在刷新視圖時就可以保證使用最新的數(shù)據(jù)。并且在代碼中簡單實現(xiàn)了刪除cell后,通過MOC調用刪除操作,使本地持久化數(shù)據(jù)和UI保持一致。
就像上面cellForRowAtIndexPath:方法中使用的一樣,F(xiàn)RC提供了兩個方法輕松轉換indexPath和NSManagedObject的對象,在實際開發(fā)中這兩個方法非常實用,這也是FRC和UITableView、UICollectionView深度融合的表現(xiàn)。
- (id)objectAtIndexPath:(NSIndexPath *)indexPath;
- (nullable NSIndexPath *)indexPathForObject:(id)object;
Fetched Results Controller Delegate
// Cell數(shù)據(jù)源發(fā)生改變會回調此方法,例如添加新的托管對象等
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(nullable NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(nullable NSIndexPath *)newIndexPath {
switch (type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeUpdate: {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
Employee *emp = [fetchedResultController objectAtIndexPath:indexPath];
cell.textLabel.text = emp.name;
}
break;
}
}
// Section數(shù)據(jù)源發(fā)生改變回調此方法,例如修改section title等。
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id
)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch (type) {
case NSFetchedResultsChangeInsert:
[tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
default:
break;
}
}
// 本地數(shù)據(jù)源發(fā)生改變,將要開始回調FRC代理方法。
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[tableView beginUpdates];
}
// 本地數(shù)據(jù)源發(fā)生改變,F(xiàn)RC代理方法回調完成。
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[tableView endUpdates];
}
// 返回section的title,可以在這里對title做進一步處理。這里修改title后,對應section的indexTitle屬性會被更新。
- (nullable NSString *)controller:(NSFetchedResultsController *)controller sectionIndexTitleForSectionName:(NSString *)sectionName {
return [NSString stringWithFormat:@"sectionName %@", sectionName];
}
上面就是當本地持久化數(shù)據(jù)發(fā)生改變后,被回調的FRC代理方法的實現(xiàn),可以在對應的實現(xiàn)中完成自己的代碼邏輯。
在上面的章節(jié)中講到刪除cell后,本地持久化數(shù)據(jù)同步的問題。在刪除cell后在tableView代理方法的回調中,調用了MOC的刪除方法,使本地持久化存儲和UI保持同步,并回調到下面的FRC代理方法中,在代理方法中對UI做刪除操作,這樣一套由UI的改變引發(fā)的刪除流程就完成了。
目前為止已經(jīng)實現(xiàn)了數(shù)據(jù)和UI的雙向同步,即UI發(fā)生改變后本地存儲發(fā)生改變,本地存儲發(fā)生改變后UI也隨之改變。可以通過下面添加數(shù)據(jù)的代碼來測試一下,NSFetchedResultsController就講到這里了。
- (void)addMoreData {
Employee *employee = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:context];
employee.name = [NSString stringWithFormat:@"lxz 15"];
employee.height = @(15);
employee.brithday = [NSDate date];
employee.sectionName = [NSString stringWithFormat:@"3"];
NSError *error = nil;
if (![context save:&error]) {