NSFetchedResultsController didChangeObject带有过滤NSPredicate

Dan*_*ane 2 core-data objective-c uitableview nsfetchedresultscontroller ios

我有一个由NSFetchedResultsController支持的UITableView,它显示了用户已经加入书签的项目.可以从行内的按钮取消标记项目,这会导致问题.在项目未加书签后,它应该从表视图中消失,因为它不再与谓词匹配,但由于更新后每个部分的行计数已被更改,我得到此错误的变体:

CoreData:错误:严重的应用程序错误.在调用-controllerDidChangeContent:期间,从委托NSFetchedResultsController捕获到异常.无效更新:第0节中的行数无效.更新(3)后现有部分中包含的行数必须等于更新前该部分中包含的行数(4),加上或减去数字从该部分插入或删除的行(0插入,0删除)和加或减移入或移出该部分的行数(0移入,0移出).用户信息(null)

这是我非常简单的didChangeObject方法:

-(void)controller:(NSFetchedResultsController *)controller
  didChangeObject:(id)anObject
     atIndexPath:(NSIndexPath *)indexPath
   forChangeType:(NSFetchedResultsChangeType)type
    newIndexPath:(NSIndexPath *)newIndexPath
{

[super controller:controller didChangeObject:anObject atIndexPath:indexPath forChangeType:type newIndexPath:newIndexPath];
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

}
Run Code Online (Sandbox Code Playgroud)

有没有什么方法可以指示NSFetchedResultsController不会出现不匹配的计数?或者我是否需要完全不同的方法?

Mar*_*n R 8

您的didChangeObject委托方法看起来非常不完整,特别是它不会检查发生了哪个事件(插入,删除或更新).

您可以在NSFetchedResultsControllerDelegate协议文档中找到模板.该方法看起来通常类似于:

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{
    UITableView *tableView = self.tableView;
    switch(type) {
        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
            break;

        case NSFetchedResultsChangeUpdate:
            [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
            [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
            break;
    }
}
Run Code Online (Sandbox Code Playgroud)

您还应该实现controller:didChangeSection:atIndex:forChangeType: 委托方法.

我不明白是什么

[super controller:controller didChangeObject:anObject atIndexPath:indexPath forChangeType:type newIndexPath:newIndexPath];
Run Code Online (Sandbox Code Playgroud)

打电话是为了!

  • @Dane:但是如果一个项目"未加书签"并且不再与谓词匹配,那么将使用`NSFetchedResultsChangeDelete`事件调用`didChangeObject`.你真的应该实现完整的委托方法! (2认同)