IGListKit
IGListKit copied to clipboard
Crashes on iOS 16 after updating IGListKit from 4.0.0 to 5.0.0
Hello, After we updated IGListKit to 5.0.0 we started observing crashes related to laying out cells in collection views.
Fatal Exception: NSInternalInconsistencyException
Height of item 0 in section 0 (100 pt) must be less than or equal to container (0 pt) accounting for section insets {0, 0, 0, 0}. Delegate class: _TtC9AppNameP33_3252A8D0199CBA1CE0F628B039E44F6B26IconImageSectionController
Trace
Fatal Exception: NSInternalInconsistencyException
0 CoreFoundation 0xa248 __exceptionPreprocess
1 libobjc.A.dylib 0x17a68 objc_exception_throw
2 Foundation 0x546958 -[NSMutableDictionary(NSMutableDictionary) initWithContentsOfFile:]
3 AppName 0x242eba0 -[IGListCollectionViewLayout _calculateLayoutIfNeeded] + 543 (IGListCollectionViewLayout.mm:543)
4 UIKitCore 0x76828 -[UICollectionViewData _prepareToLoadData]
5 UIKitCore 0x444020 -[UICollectionViewData validateLayoutInRect:]
6 UIKitCore 0x29ac8 -[UICollectionView layoutSubviews]
7 UIKitCore 0x4cec -[UIView(CALayerDelegate) layoutSublayersOfLayer:]
8 QuartzCore 0xa4e8 CA::Layer::layout_if_needed(CA::Transaction*)
9 UIKitCore 0xd2ae8 -[UIView(Hierarchy) layoutBelowIfNeeded]
10 UIKitCore 0x4f33e4 __47-[UICollectionViewAnimation startWithAnimator:]_block_invoke
11 UIKitCore 0x316d0 +[UIView(Animation) performWithoutAnimation:]
12 UIKitCore 0xa3668 -[UICollectionViewAnimation startWithAnimator:]
13 UIKitCore 0x707948 -[UICollectionView _startViewAnimationsWithContext:oldVisibleViews:reorderedViewAttributesTable:viewAnimator:viewAnimationsCompletedDispatchGroup:]
14 UIKitCore 0x4e2df0 __102-[UICollectionView _updateWithItems:tentativelyForReordering:propertyAnimator:collectionViewAnimator:]_block_invoke_2
15 UIKitCore 0xd0af0 +[UIView _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:]
16 UIKitCore 0xa3da8 +[UIView(UIViewAnimationWithBlocks) animateWithDuration:delay:options:animations:completion:]
17 UIKitCore 0x3145e8 -[UICollectionView _updateWithItems:tentativelyForReordering:propertyAnimator:collectionViewAnimator:]
18 UIKitCore 0x3135a8 -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:collectionViewAnimator:]
19 UIKitCore 0x27111c -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:animator:animationHandler:]
20 AppName 0x24298f0 __43-[IGListBatchUpdateTransaction _applyDiff:]_block_invoke.9 + 190 (IGListBatchUpdateTransaction.m:190)
21 UIKitCore 0x316d0 +[UIView(Animation) performWithoutAnimation:]
22 AppName 0x2429614 -[IGListBatchUpdateTransaction _applyDiff:] + 192 (IGListBatchUpdateTransaction.m:192)
23 AppName 0x24291c8 -[IGListBatchUpdateTransaction _didDiff:onBackground:] + 155 (IGListBatchUpdateTransaction.m:155)
24 AppName 0x2428df4 -[IGListBatchUpdateTransaction _diff] + 124 (IGListBatchUpdateTransaction.m:124)
25 AppName 0x24262d8 -[IGListAdapterUpdater update] + 124 (IGListAdapterUpdater.m:124)
26 AppName 0x24260f0 __44-[IGListAdapterUpdater _queueUpdateIfNeeded]_block_invoke + 73 (IGListAdapterUpdater.m:73)
These crashes didn't occur on iOS 17 and 18.
I've gone through the changelist checking commit by commit when the regression started, and it seems this commit is at fault: https://github.com/Instagram/IGListKit/commit/032e1b0b8367e68ef3015f0dc7dfe2f3ff2bae0c - namely the change which removes the if with an early return, which guarded the diff from happening.
On iOS 16 in our case the collection view's window seems to be nil, which is why the if was triggering, whereas on 17 and 18 the window was not nil.
To give some more context, for this collection view we are not laying out the view. If we lay it out explicitly, the crash is no longer there. On 4.0.0 the code inside the if laid out the view, however, but since that is gone the crashes started happening.
I'm thinking whether we should guarantee the view is already laid out for IGListKit?
Thank you in advance
Hey @aleksanderlorenc-lw!
Sorry to hear that v5 started introducing this crash issue. Looking at Maxime's explanation in that commit, the check was removed since it was causing a lot of thrash to occur that was impacting performance.
Certainly in recent versions of iOS, IGListKit has had to change its behaviour to match Apple's changes to UICollectionView. Namely, a lot of the original UICollectionView behaviour was to do a complete reload whenever invalid state was detected, but that's being slowly replaced with straight up crashes/exceptions to encourage developers to work out why the state was invalid and to properly fix those issues.
I definitely think you should add a check in your code to confirm if the view is laid out like you proposed, but if you're interested, it might also be great if we could build a similar check into IGListKit to also catch those sorts of issues for others!
What do you think?
Hey @TimOliver, from our side we have made sure the view is always laid out before starting IGListKit work and additionally we are dropping iOS 16 soon, so the issue should be gone. Not really sure how much of the users would have a similar case, but maybe a simple debug assert telling the users the view should be laid out at that point would be helpful