I'm getting crashes from deep inside Apple's layout code for a UICollectionViewFlowLayout and I have no idea how to address these (stack trace below). Any suggestions would be greatly appreciated.
Details:
#0. Crashed: com.apple.main-thread
0 libsystem_platform.dylib 0x1879490d4 __bzero + 36
1 UIKit 0x18e824e40 -[UICollectionViewData _updateItemCounts] + 544
2 UIKit 0x18e824e40 -[UICollectionViewData _updateItemCounts] + 544
3 UIKit 0x18e8e67e0 -[UICollectionViewData numberOfSections] + 28
4 UIKit 0x18f086bc0 -[UICollectionViewFlowLayout _getSizingInfosWithExistingSizingDictionary:] + 612
5 UIKit 0x18f088834 -[UICollectionViewFlowLayout _fetchItemsInfoForRect:] + 152
6 UIKit 0x18e8e66b4 -[UICollectionViewFlowLayout prepareLayout] + 224
7 UIKit 0x18e7cf574 -[UICollectionViewData _prepareToLoadData] + 164
8 UIKit 0x18e7ceb5c -[UICollectionViewData validateLayoutInRect:] + 100
9 UIKit 0x18e7ce55c -[UICollectionView layoutSubviews] + 212
10 UIKit 0x18e76fa80 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1196
11 QuartzCore 0x18bc1d9d8 -[CALayer layoutSublayers] + 148
12 QuartzCore 0x18bc124cc CA::Layer::layout_if_needed(CA::Transaction*) + 292
13 QuartzCore 0x18bc1238c CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 32
14 QuartzCore 0x18bb8f3e0 CA::Context::commit_transaction(CA::Transaction*) + 252
15 QuartzCore 0x18bbb6a68 CA::Transaction::commit() + 512
16 QuartzCore 0x18bbb7488 CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 120
17 CoreFoundation 0x18886a0c0 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
18 CoreFoundation 0x188867cf0 __CFRunLoopDoObservers + 372
19 CoreFoundation 0x188868180 __CFRunLoopRun + 1024
20 CoreFoundation 0x1887962b8 CFRunLoopRunSpecific + 444
21 GraphicsServices 0x18a24a198 GSEventRunModal + 180
22 UIKit 0x18e7dd7fc -[UIApplication _run] + 684
23 UIKit 0x18e7d8534 UIApplicationMain + 208
24 AppName Mobile 0x1000333e8 main (main.m:16)
25 libdispatch.dylib 0x1877795b8 (Missing)
We finally found this one. It wasn't the performBatchUpdates issue reported on a lot of other cards. The root cause was one our data sources would return a negative number for item count. The SDK is using an unsigned int, so setting a negative rolled over, and would try to allocate billions of cells (34 GB of virtual memory and counting). It would eventually crash.
There is a rampant problem with item counts and performBatchUpdates
. Specifically, you may run into discrepancies and an OS assert if these are not in sync. An assert is not a crash.
I do suspect that this is what you encountered here, and if so, this question may be a duplicate of:
Assert or not, a defensive approach is to guard the item count as excellently outlined in Fang-Pen Lin's(†)UICollectionView invalid number of items crash problem and solution blog post:
func updateItems(updates: [ItemUpdate]) {
collectionView.performBatchUpdates({
for update in updates {
switch update {
case .Add(let index):
collectionView.insertItemsAtIndexPaths([NSIndexPath(forItem: index, inSection: 0)])
itemCount += 1
case .Delete(let index):
collectionView.deleteItemsAtIndexPaths([NSIndexPath(forItem: index, inSection: 0)])
itemCount -= 1
}
}
}, completion: nil)
}
†Full Credit
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With