UICollectionView 快照需要太长时间才能重新应用

问题描述 投票:0回答:1

我有一个带有大量数据源的 UICollectionView,例如30000+ 项;并且数据源根据屏幕方向(即纵向、横向)而变化,因此每当屏幕旋转时我都会重新创建并重新应用快照。

我注意到,第一次

UICollectionView
加载单元格相对较快,但随后重新应用不同的快照(屏幕旋转后)需要很长时间。

这是可以理解的,因为后续重新加载需要大量计算现有快照和新快照的差异,所以我想知道是否有一种方法可以应用快照而不计算差异?由于快照的大小,我不想在内存中保留两个快照副本。或者我可以通过在应用全尺寸快照之前先应用空快照来解决此问题吗?

谢谢!

编辑:

我做了一些粗略的测试:

带有空快照

首次加载:

2022-08-05 07:47:11.666847+1000 before apply
2022-08-05 07:47:11.667139+1000 after apply empty snapshot
2022-08-05 07:47:11.788821+1000 after creating full-sized snapshot
2022-08-05 07:47:13.022973+1000 after applying full-sized snapshot

总计:~1.36

旋转后重新加载:

2022-08-05 07:48:05.238174+1000 before apply
2022-08-05 07:48:08.708084+1000 after apply empty snapshot
2022-08-05 07:48:08.900322+1000 after creating full-sized snapshot
2022-08-05 07:48:12.034542+1000 after applying full-sized snapshot

总计:~6.80

没有空快照

首次加载:

2022-08-05 07:49:33.149233+1000 Setting columns…
2022-08-05 07:49:33.279147+1000 before apply
2022-08-05 07:49:33.401114+1000 after creating full-sized snapshot
2022-08-05 07:49:34.402645+1000 after applying full-sized snapshot

总计:~1.25

旋转后重新加载:

2022-08-05 07:50:26.829309+1000 Reload due to trait collection change…
2022-08-05 07:50:27.270996+1000 Setting columns…
2022-08-05 07:50:31.187630+1000 before apply
2022-08-05 07:50:31.410154+1000 after creating full-sized snapshot
2022-08-05 07:50:45.879088+1000 after applying full-sized snapshot

总计:~19.05

结论:

  • 首次加载:无需创建和应用空快照,速度更快,1.25 vs 1.36
  • 后续加载:在应用全尺寸快照之前应用空快照比仅应用全尺寸快照要快得多,因为它节省了计算两个全尺寸快照之间差异的时间。

所以问题仍然存在:有什么办法可以让它更快吗?如果不是,我可能需要回到旧的

UICollectionViewDataSource
提供细胞的方式。

ios swift uicollectionview uicollectionviewcompositionallayout uicollectionviewdiffabledatasource
1个回答
0
投票

使用

dataSource.applySnapshotUsingReloadData()
apply(_, animatingDifferences: )
快得多,特别是在您更改大量数据的情况下,因为它不计算差异。通过进行此更改,我在处理 30k+ 行的代码中消除了 3+ 秒的延迟。

https://developer.apple.com/documentation/uikit/uicollectionviewdiffabledatasource/3804469-applysnapshotusingreloaddata

请注意,它仅在 iOS 15 或更高版本上可用,因此如果您仍然需要支持旧版本,您可能需要这样换行:

if #available(iOS 15, *) {
    self?.dataSource.applySnapshotUsingReloadData(snapshot)
} else {
    self?.dataSource.apply(snapshot, animatingDifferences: false)
}
© www.soinside.com 2019 - 2024. All rights reserved.