我的fetchedResultsController最初是这样创建的(在viewDidLoad中):
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"Cat" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:@"age" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"age"
cacheName:@"whatever"];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
这很好用,结果显示在我的表视图中。但是,按下某些按钮时我想过滤结果。所以我这样做:
NSPredicate *predicate = ...; //based on buttons pressed
[[self.fetchedResultsController fetchRequest] setPredicate:predicate];
[NSFetchedResultsController deleteCacheWithName:@"whatever"];
NSError * error = nil;
[self.fetchedResultsController performFetch:&error];
if (error) {
DDLogError(@"[%@ %@] fetchedResultsController ERROR: %@", THIS_FILE, THIS_METHOD, error.localizedDescription);
}
[self.myTableView reloadData];
问题是表视图没有重新加载。如果我滚动表格视图,单元格会根据新数据进行更改,但每次尝试过滤时,部分和行数都不会改变。
我错过了什么?
答案 0 :(得分:1)
您需要在对fetchResultController进行任何更改之前删除缓存
来自apple doc:NSFetchedResultsController Class Reference
如果您正在使用缓存,则必须先调用deleteCacheWithName: 更改任何获取请求,其谓词或其排序 描述。您不能重复使用相同的获取结果控制器 除非您将cacheName设置为nil。
(可选)控制器应使用的缓存文件的名称 (传递nil可以防止缓存)。使用缓存可以避免开销 计算部分和索引信息。
答案 1 :(得分:0)
我怀疑您需要根据更新的数据插入和删除表格视图行。
您在其他答案的评论中写的错误消息保留了线索。
您应该具体阅读的内容是标题下的文字: 行和部分的批量插入,删除和重新加载 。
然而,在此之前,当您更改NSFetchedResultsController
时,应检查是否实现了NSFetchedResultsController委托方法来管理更改。 Apple提供的标准代码应包括在表视图控制器中。您不需要更改/覆盖此标准代码。
请参阅此Apple documentation。
基本上对于“典型使用”案例,您需要实现四种典型的委托方法:
(void)controllerWillChangeContent:(NSFetchedResultsController *)controller
; (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
; (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
; (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
。 在的情况下,您已经包含了这些NSFetchedResultsController委托方法,您可能需要考虑使用UITableView委托方法beginUpdates
和endUpdates
方法: / p>
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation: (UITableViewRowAnimation)animation;
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation: (UITableViewRowAnimation)animation;
所以你应该尝试使用以下代码块:
tableView.beginUpdates;
tableView.insertRowsAtIndexPaths:indexPaths withRowAnimation:animation;
tableView.deleteRowsAtIndexPaths:indexPaths withRowAnimation:animation;
tableView.endUpdates
您显然需要为insert和delete方法创建indexPaths数组。