gpt4 book ai didi

ios - UICollectionView performBatchUpdates : asserts unexpectedly if view needs layout?

转载 作者:可可西里 更新时间:2023-11-01 04:23:23 25 4
gpt4 key购买 nike

如果我从 viewWillAppear: 内部、viewDidAppear: 内部、这些方法之间或集合的任何时间调用 -[UICollectionView performBatchUpdates:] View 没有被更大的 UIView View 层次结构布局, Collection View 将断言:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections. The number of sections contained in the collection view after the update (X) must be equal to the number of sections contained in the collection view before the update (X), plus or minus the number of sections inserted or deleted (X inserted, 0 deleted).'

其中“X”是我插入的项目的任意数量。我已确认数据源正在正确更新并且更新中的索引路径是正确的。

当数据源刚刚在调用 performBatchUpdates: 之前更新时, Collection View 状态如何与数据源保持一致?似乎有什么意外地触发了 reloadData。

最佳答案

UICollectionView 似乎有特殊行为(错误?):如果它需要布局,则 performBatchUpdates: 在调用更新 block 之前有效地充当 reloadData,它呈现无论您计划在更新 block 期间进行什么更改,都会对 Collection View 簿记产生有害影响。

如果您计划在 View 被正确布局之前将批量更新应用到 View (例如从快速变化的数据模型环境中的通知处理程序),您需要确保在 viewWillAppear: 你在 Collection View 上调用 layoutIfNeeded。这将防止 Collection View 在调用 performBatchUpdates: 时重新加载。

我们通过在我们的 Collection View 数据源 numberOfSections 方法中放置一个日志来发现这种行为,并打印出这个回溯以查看它是从哪里调用的:

2014-11-12 15:30:06.173 CVCrasher[66830:6387719] [CV] #sections stack: (
0 CVCrasher 0x000000010ba9122d -[MyViewController numberOfSectionsInCollectionView:] + 61
1 UIKit 0x000000010cfc2811 -[UICollectionViewData _updateItemCounts] + 147
2 UIKit 0x000000010cfc4a89 -[UICollectionViewData numberOfSections] + 22
3 UIKit 0x000000010cfaebae -[UICollectionViewFlowLayout _getSizingInfos] + 348
4 UIKit 0x000000010cfafca9 -[UICollectionViewFlowLayout _fetchItemsInfoForRect:] + 526
5 UIKit 0x000000010cfab51f -[UICollectionViewFlowLayout prepareLayout] + 257
6 UIKit 0x000000010cfc2a10 -[UICollectionViewData _prepareToLoadData] + 67
7 UIKit 0x000000010cfc30e9 -[UICollectionViewData validateLayoutInRect:] + 54
8 UIKit 0x000000010cf8b7b8 -[UICollectionView layoutSubviews] + 170
9 UIKit 0x000000010c9d1973 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 521
10 QuartzCore 0x0000000110cf2de8 -[CALayer layoutSublayers] + 150
11 QuartzCore 0x0000000110ce7a0e _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
12 UIKit 0x000000010c9c5847 -[UIView(Hierarchy) layoutBelowIfNeeded] + 611
13 UIKit 0x000000010cf9c7b7 -[UICollectionView performBatchUpdates:completion:] + 164
...

在这里,您可以清楚地看到对 performBatchUpdates: 的调用正在访问数据源,并在应用更新之前与更改后的模型保持一致。当 block 本身被调用时, Collection View 将抛出一个断言,就像我在原始问题中展示的那样。

tl;dr - 当 UICollectionView 需要布局时,performBatchUpdates: 有效地充当对 reloadData 的调用,并将使批量更新 block 断言因为记账不好。在 viewWillAppear: 中调用 layoutIfNeeded 以避免此行为。

关于ios - UICollectionView performBatchUpdates : asserts unexpectedly if view needs layout?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26898835/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com