使用 NSFetchedResultsController 时 CoreData 与 UITableView 有啥关系?

Posted

技术标签:

【中文标题】使用 NSFetchedResultsController 时 CoreData 与 UITableView 有啥关系?【英文标题】:How is CoreData related to UITableView when using NSFetchedResultsController?使用 NSFetchedResultsController 时 CoreData 与 UITableView 有什么关系? 【发布时间】:2016-03-14 08:17:32 【问题描述】:

你肯定遇到了这个错误:

CoreData:错误:严重的应用程序错误。捕获到异常 在调用期间从 NSFetchedResultsController 的委托 -controllerDidChangeContent:。无效更新:无效的节数。之后表格视图中包含的节数 更新 (8) 必须等于包含在 更新前的表视图(8),加减数 插入或删除的部分(1 个插入,0 个删除)。与用户信息 (空)

这条消息对我来说没有意义,因为 CoreData 与 NSFetchedResultsController 但 CoreData 与表视图无关。 (如我错了请纠正我) 我理解它的方式,tableview 和 NSFetchedResultsController 之间的唯一链接是在 NSFetchedResultsController 的 委托中,当我们使用 controller(didChangeObject:)controller(didChangeSection:)

ios 框架怎么可能知道 tableView 的节数,而它甚至不是强制性的(推荐但不是强制性的)使用 UITableView... 它应该只能检查 NSFetchedResultsController 结果 fetchedObjects 结果数组,而不是在 tableview 中。

【问题讨论】:

【参考方案1】:

通常,控制器的委托以以下方式实现(摘自 Apple 的核心数据编程指南):

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller

    [[self tableView] endUpdates];

tableView 收到endUpdates 消息时,它会做两件在我们的上下文中很重要的事情:

    计算自beginUpdates 以来插入和/或删除的节数(使用insertSections:withRowAnimation 方法)

    检查这些更改是否反映在数据源中。在您的情况下,它们不是:通过在表视图上调用 insertSections:withRowAnimation 插入了 1 个部分,但是当询问部分计数时,数据源仍然返回 8。这基本上就是错误消息所说的内容。

所以表视图发现它的状态是不一致的,它会抛出异常。

我们仍然使用controllerDidChangeContent 委托方法。我们再来看看报错信息:

从委托中捕获了一个异常 NSFetchedResultsController 在调用期间 -controllerDidChangeContent

所以NSFetchedResultsControllertry 块内对其委托调用controllerDidChangeContent 并捕获异常。然后它重新抛出它。

长话短说:NSFetchedResultsController 对表格视图一无所知 - 它只是捕获了恰好在 UITableView 中的 endUpdates 方法中引发的异常。

【讨论】:

以上是关于使用 NSFetchedResultsController 时 CoreData 与 UITableView 有啥关系?的主要内容,如果未能解决你的问题,请参考以下文章

核心数据保存竞争条件错误

在 Swift 3 中难以配置 NSFetchedResultsController

为啥 beginUpdates/endUpdates 会重置表视图位置以及如何阻止它这样做?

测试使用

第一篇 用于测试使用

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?