我在使用带有 diffable 数据源的 UITableView 时遇到了问题。在我的应用程序中,当用户修改一个项目时,它可能会更改在同一表视图中显示的另一个项目。问题是,在我创建和应用包含两个项目新值的新快照后,间接更改的项目的 UI 没有更新。
起初,我认为 diffable 数据源能够检测不同快照中项目的值更改。例如,它可能是这样工作的:如果它发现两个快照都包含相同的项目(即,在两个快照中的项目具有相同的哈希值),则比较它们的值并更新表视图中该项目的行,如果该值更改。然而,后来我意识到它可能不是这样工作的,因为 diffable 数据源没有定义任何 API 来获取和比较项目值(我最初的想法是它使用description
计算属性和 ==
操作,但现在我相信这不是真的)。
因此,我目前的理解是 diffable 数据源使用项目哈希来检测 项目订单更改 (即插入新项目,旧项目仍存在等),而不是 项目值更改 (即旧项目仍存在但其值已更改)。如果这种理解是正确的,那么就会引出这个问题:如何使用 diffable 数据源实现以下场景?
- 一个项目有若干属性。其中一种属性(我们称之为属性A)在UI中显示,但不用于生成哈希值。
- 该项目存在于旧和新的快照中,但其属性A发生了变化。所以需要更新其UI。
在旧的UITableView
API中,可以通过调用reloadRows()
或reloadData()
来实现这一点。但是如何使用可差异数据源实现呢?
更新:
经过时间的实验和解决问题,我认为以上问题的理解是错误的。请看下面我的答案。我相信那说明了可差分数据源的工作方式。我希望它能对那些会遇到同样困惑的人有所帮助。如果你有不同的看法,请留下你的答案,我很乐意被证明是错的。真的。
==
。 - mattHashable
在 Swift 中要求Equatable
。但是在 diffable data source 中没有任何地方提到如何使用==
。在 WWDC 2019 Session 220 视频的示例代码中,==
函数的定义与hash(into:)
函数基本相同。在我看来,这非常具有误导性。除非我完全误解了它,否则 diffable data source 实际上非常好地处理了两个具有相同哈希值但不相等的项的情况。我认为这是 diffable data source 设计的一部分,演讲者们真的应该明确提到这一点。 - rayx==
运算符比较时结果为真。这是数据源识别对象的关键方法,这也是它们被称为标识符的原因!如果一个对象在第 1 行,而一个等于它的对象现在在第 3 行,则它们必须是同一个对象。哈希性只是一种工具,可以使此判断在不需要每次检查每个值的情况下更快速地进行。 - mattreloadItems
。 编辑:我认为这是NSFetchedResultsController中的一个错误。NSFetchedResultsController应该使用reloadItems
,但它没有。这里是手动生成reloadItems的解决方案。https://dev59.com/G1MH5IYBdhLWcg3wvyE4#65293427 - Wilko X