应用场合:配合Core Data和Table View使用,Core Data存储数据,Table View显示数据
1.在需要显示数据的视图控制器(包含有table view)中添加NSFetchedResultsController实例变量
NSFetchedResultsController *_fetchedResultsController;
}
2.惰性实例化NSFetchedResultsController实例变量
-(NSFetchedResultsController *)fetchedResultsController
{
if(_fetchedResultsController == nil)
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; //创建一个请求
//实体描述
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Location" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
//设置排序
NSSortDescriptor *sortDescriptor1 = [NSSortDescriptor sortDescriptorWithKey:@"category" ascending:YES];
NSSortDescriptor *sortDescriptor2 = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:YES];
[fetchRequest setSortDescriptors:@[sortDescriptor1,sortDescriptor2]];
//每次获取20个数据
[fetchRequest setFetchBatchSize:20];
//按“category”关键字分组,cacheName参数的名字用于唯一标记获取的数据结果,fetchedResultsController会将这些数据缓存起来
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"category" cacheName:@"Locations"];
_fetchedResultsController.delegate = self;
}
return _fetchedResultsController;
}
3.让视图控制器实现NSFetchedResultsController协议
@end
4.调用方法开始获取Core Data存储的数据
[super viewDidLoad];
[self performFetch];
}
-(void)performFetch
{
NSError *error;
if(![self.fetchedResultsController performFetch:&error])
{
//添加处理错误情况的代码
return;
}
}
5.添加以下代码
_fetchedResultsController.delegate = nil;
}
6.实现table view数据源返回行数的方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
return [sectionInfo numberOfObjects];
}
7.获取Core Data存储的某一个数据(实体)时用以下语句,之后便可对该对象进行删除,修改等操作,然后再同步到Core Data数据(参考Core Data博文)
Location *location = [self.fetchedResultsController objectAtIndexPath:indexPath];
8.实现NSFetchedResultsController协议方法
#pragma mark - NSFetchedResultsControllerDelegate
-(void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
NSLog(@"*** controllerWillChangeContent");
[self.tableView beginUpdates];
}
-(void)controller:(NSFetchedResultsController *)controller didChangeObject:(nonnull id)anObject atIndexPath:(nullable NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(nullable NSIndexPath *)newIndexPath
{
switch (type) {
case NSFetchedResultsChangeInsert:
NSLog(@"*** NSFetchedResultsChangeInsert (object)");
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
NSLog(@"*** NSFetchedResultsChangeDelete (object)");
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
NSLog(@"*** NSFetchedResultsChangeUpdate (object)");
//添加调用设置table view cell内容的方法,该方法需要另行新建
break;
case NSFetchedResultsChangeMove:
NSLog(@"*** NSFetchedResultsChangeMove (object)");
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
-(void)controller:(NSFetchedResultsController *)controller didChangeSection:(nonnull id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
switch (type) {
case NSFetchedResultsChangeInsert:
NSLog(@"*** NSFetchedResultsChangeInsert (section)");
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
NSLog(@"*** NSFetchedResultsChangeDelete (section)");
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeMove: break;
case NSFetchedResultsChangeUpdate: break;
}
}
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
NSLog(@"*** controllerDidChangeContent");
[self.tableView endUpdates];
}
9.实现以下方法,当滑动删除cell时,同时同步到Core Data数据库
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
if(editingStyle == UITableViewCellEditingStyleDelete)
{
Location *location = [self.fetchedResultsController objectAtIndexPath:indexPath];
[self.managedObjectContext deleteObject:location];
NSError *error;
if(![self.managedObjectContext save:&error])
{
//添加处理错误情况的代码
return;
}
}
}
10.实现table view分组相关的协议方法
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[self.fetchedResultsController sections] count];
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
return [sectionInfo name];
}
11.可按以下格式设置cell的显示
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Location"];
[self configureCell:cell atIndexPath:indexPath]; //configureCell:atIndexPath:方法用于详细设置如何显示cell的内容,需另行编写
return cell;
}