【发布时间】:2021-07-20 22:41:11
【问题描述】:
在处理一个新项目时,我们的团队决定使用UICollectionViewDiffableDataSource 来处理我们的集合视图。它工作正常,但我们通过在线工具记录了(不常见的)崩溃,消息为Invalid parameter not satisfying: initialSnapshot.numberOfSections == initialSections.count。我们似乎无法在本地重现此内容。
崩溃发生在我们用新数据更新数据源的地方,特别是dataSource.apply(snapshot)。我们不确定这是如何发生的,因为创建的数据总是相同的。
具体来说,处理这个视图的单位决定放弃创建截面模型,而是决定使用Int 作为截面标识符,因为他们不想使用截面,只是显示项目。这是我以前从未见过的一件事,但 Int 满足标识符的要求,因此代码确实可以正确编译。
代码如下:
集合视图和数据源创建
这些变量位于以编程方式创建的 UIView 的类中。
var collectionView = UICollectionView(frame: .zero, collectionViewLayout: createCollectionViewLayout())
lazy var dataSource = UICollectionViewDiffableDataSource<Int, URL>(collectionView: collectionView, cellProvider: provideCell(_:indexPath:item:))
更新数据源
func updateUI() {
var snapshot = dataSource.snapshot()
snapshot.deleteAllItems()
snapshot.appendSections([0])
if let urls = viewModel?.imageUrls {
snapshot.appendItems(urls)
}
dataSource.apply(snapshot)
}
在我测试过的所有(生产)案例中,viewModel?.imageUrls 在第一次调用时为空,然后在第二次调用和之后的所有调用中包含项目。项目的数量通常不会改变。
我考虑过不使用dataSource.snapshot() 而是创建一个新的,这样我也不必每次都调用deleteAllItems()。但是,当我不确定这是否真的解决了问题时,我不想只是将其作为解决方案。
以前有没有人遇到过这样的问题?使用Int 作为部分标识符是否正确?崩溃的其他原因可能是什么?
【问题讨论】:
-
您关于创建新快照的建议可能是一个不错的建议,快照是可区分的,而数据源的工作就是进行区分。如果您正在操作现有的快照,那么您就是在做差异化自己的工作。 Int 可以用作节标识符。
标签: ios swift uicollectionview uikit uicollectionviewdiffabledatasource