首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带有过滤NSFetchedResultsController NSPredicate的NSPredicate

带有过滤NSFetchedResultsController NSPredicate的NSPredicate
EN

Stack Overflow用户
提问于 2013-09-11 17:57:00
回答 2查看 3.2K关注 0票数 2

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

CoreData:错误:严重的应用程序错误。在调用NSFetchedResultsController :时,从委托-controllerDidChangeContent捕获了一个异常。无效更新:第0节中的行数无效。更新(3)后包含在现有节中的行数必须等于更新(4)之前包含在该节中的行数,加上或减去从该节插入或删除的行数(0插入,0删除),加上或减去移动到或移出该节的行数(0移动,0移出)。使用userInfo (null)

下面是我非常简单的didChangeObject方法:

代码语言:javascript
运行
复制
-(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];

}

我有什么办法可以指示NSFetchedResultsController不要为不匹配的计数而流汗?还是我需要一个完全不同的方法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-11 18:06:03

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

您可以在NSFetchedResultsControllerDelegate协议文档中找到一个模板。该方法通常看起来类似于以下内容:

代码语言:javascript
运行
复制
- (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;
    }
}

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

我不明白

代码语言:javascript
运行
复制
[super controller:controller didChangeObject:anObject atIndexPath:indexPath forChangeType:type newIndexPath:newIndexPath];

打电话给你!

票数 8
EN

Stack Overflow用户

发布于 2015-05-07 09:37:59

马丁·R给出了一个很好的答案,但他忽略了一件重要的事情:

如果FetchControllerProtocol想同时刷新许多行,它可能会崩溃。

苹果博士给出了这个过程的一个非常清晰的典型例子。用beginUpdates和endUpdates方法包围表更改是很重要的。

代码语言:javascript
运行
复制
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView beginUpdates];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView endUpdates];
}

如果有节,还应该实现该节刷新。

代码语言:javascript
运行
复制
- (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];
            break;
    }
}

希望这能有所帮助

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18748104

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档