iOS 13 上 TableView 错误的 Diffable 数据源:移动的关联不一致
Posted
技术标签:
【中文标题】iOS 13 上 TableView 错误的 Diffable 数据源:移动的关联不一致【英文标题】:Diffable data source for TableView error on iOS 13: Inconsistent associations for moves 【发布时间】:2019-08-01 13:18:31 【问题描述】:我正在将我当前的 UITableview 更新为 ios 13 UITableViewDiffableDataSource
提供的可区分数据源。
我有一个带有自定义对象的数组(实现 isEqual: 方法)。在 viewWillAppear 上,我从磁盘加载数据并调用申请快照。
-(void)updateTableViewAnimated:(BOOL)animated API_AVAILABLE(ios(13.0))
NSDiffableDataSourceSnapshot *snapshot = [[NSDiffableDataSourceSnapshot alloc]init];
[snapshot appendSectionsWithIdentifiers:@[@"sectionTitle"]];
[snapshot appendItemsWithIdentifiers:self.playlists];
[self.diffDataSource applySnapshot:snapshot animatingDifferences:animated];
一切都加载了。但是当尝试从数组中删除一个项目并再次调用updateTableViewAnimated:
时,我得到了一个异常。
*** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“移动关联不一致”
这是什么意思? 我该如何解决?
【问题讨论】:
您找到解决方案了吗? 【参考方案1】:更新答案
我很幸运能够对我提出的有关此问题的错误作出回应。事实证明,我的模型对象进行了不正确的哈希和平等检查。
我的 swift 结构符合 Hashable,但提供了 Equatable 的自定义实现,我只比较 ID 属性以确定相等性。这意味着两个对象可能被认为是相等的,但具有不同的哈希值,这会混淆 diffing 算法。
为了解决这个问题,我简单地删除了 Equatable 的自定义实现,并使用了合成版本。
您在问题中声明您实现了isEqual
,即ObjC,类似于Swift 的==
,但您可能没有提供在所有情况下都与您的isEqual
实现一致的hash
实现。
原始答案(在这种情况下可能不正确,但如果队列是问题,可能仍然有用)
我不知道这是否与您遇到的问题相同,但在我的情况下,它是由从不同队列调用的 applySnapshot
方法引起的。
高级数据源 WWDC 会议提到 applySnapshot
必须在后台队列或主队列上以独占方式调用,但不要同时从两者调用。 Advanced Data Sources WWDC 2019 - 32:00
在我的例子中,我使用组合发布者来响应我的数据源上的更改,并且该发布者有时会在主线程或后台线程上发送值。为了解决我的问题,我将.receive(on: RunLoop.Main)
添加到链中。
在您的情况下,也许您可以使用您希望它运行的队列(无论是主队列还是后台队列)将调用 updateTableViewAnimated:
的任何内容包装在 dispatch_async
调用中。
【讨论】:
【参考方案2】:添加到 Jasarien 信息丰富的答案,
您需要记住 UICollectionViewDiffableDataSource
使用 hashable 来区分数据源中的项目
如果您的模型是一个结构,并且您的数据源模型中有两个项目恰好具有完全相同的值,Hashable
协议将为它们生成相同的 hashValue。
Equatable
协议也将返回 true! , 这会混淆
UICollectionViewDiffableDataSource
解决方案
确保您的数据源没有任何重复项 如果您无法避免重复,并且您不介意制动Equatable
,您可能希望在数据源中添加随机值,但不建议这样做,因为生成的值可能在任何巧合时都相等,如所述在文档中
*概率低,但有可能发生 *
根据范围的大小和跨度,某些具体值可能比其他值更频繁地表示。
【讨论】:
苹果在这里装傻。对于不同的单元格具有相同的数据是正常的。在某些情况下,tableview 会在不同的单元格中显示相同的数据。如果我将添加随机数,则不会有移动,但会针对所有数据更改情况进行插入和删除以上是关于iOS 13 上 TableView 错误的 Diffable 数据源:移动的关联不一致的主要内容,如果未能解决你的问题,请参考以下文章
UITableViewRowAction 的图标在 iOS 13 上显示,但在 iOS 12 上不显示
在 iOS 13 和 xcode 11 中,tableview 单元格的“setSelected”方法不返回完美的单元格大小
iOS:我的 TableView 标题的背景颜色在 iOS13 中不再改变
iOS 14 UICollectionView新功能之TableView