UICollectionView performBatchUpdates: unexpectedly asserted if the presentation needs layout?

If I call -[UICollectionView performBatchUpdates:] from inside viewWillAppear: inside viewDidAppear: between these methods or at any time when the collection view has not been laid out with a larger hierarchy of UIView views, the collection view will be validated with:

*** Application termination due to the uncaught exception "NSInternalInconsistencyException", Cause: "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 inserted or deleted partitions (inserted X, 0 deleted).

Where "X" is any number of elements that I inserted. I confirmed that the data source is being updated correctly and the pointer paths in the update are correct.

How will the state of the collection view be consistent with the data source when the data source was just updated just before the call to performBatchUpdates: :? Something seems to be starting reloadData unexpectedly.

+5
source share
2 answers

UICollectionView seems to have a special behavior (bug?): If it needs a layout, then performBatchUpdates: effectively acts as reloadData before calling the update block, which displays all the changes that you plan to make during the update block poisonous to bookkeeping collection.

If you plan to have batch updates applied to the view before it is properly built (for example, from a notification handler in a rapidly changing data model environment), you need to make sure that in viewWillAppear: which you call layoutIfNeeded in the collection view. This will prevent reloading the collection view when calling performBatchUpdates:

We discovered this behavior by placing the log in our data source numberOfSections data source and printing this back trace to see where it was called from:

 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 ... 

Here you can clearly see that the call to performBatchUpdates: hits the data source and becomes compatible with the modified model before the updates are applied. When the block itself is called, the collection view will invoke the statement, as shown in the original question.

tl; dr . When a UICollectionView needs a layout, performBatchUpdates: effectively acts as a reloadData call and will make the batch update block an assertion due to poor accounting. Call layoutIfNeeded in viewWillAppear: to avoid this.

+9
source

This is the expected behavior, not an error. From the documentation for performBatchUpdates :

If the collection view layout is not updated before calling this method, a reboot may occur. To avoid problems, you should update the data model in the update block or make sure the layout is updated before calling executeBatchUpdates (_: completion :).

+1
source

Source: https://habr.com/ru/post/1206756/


All Articles