I'm getting a strange crash in my UICollectionView. The crashing UICollectionView is embedded in an UICollectionView cell of another UICollectionView.
I can't reproduce the issue, it seems to happen sometimes if the inner UICollectionView get's newly initialized because the outer CollectionView is reloading it's cells.
com.apple.main-thread Crashed 0 libobjc.A.dylib objc_msgSend + 9 1 UIKit -[UICollectionViewData _setLayoutAttributes:atGlobalItemIndex:] + 60 2 UIKit __45-[UICollectionViewData validateLayoutInRect:]_block_invoke_0 + 668 3 UIKit -[UICollectionViewData validateLayoutInRect:] + 1408 4 UIKit -[UICollectionViewData layoutAttributesForElementsInRect:] + 82 5 UIKit -[UICollectionView setCollectionViewLayout:animated:] + 1644 6 MyApp BSCTopnewsCollectionView.m line 52 -[BSCTopnewsCollectionView setupBSCTopnewsCollectionView] 7 MyApp BSCTopnewsCollectionView.m line 27 -[BSCTopnewsCollectionView setWeakDelegatePointer:] 8 Myapp BSCFrontPageViewController.m line 550 -[BSCFrontPageViewController collectionView:cellForItemAtIndexPath:] 9 UIKit -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:] + 252 10 UIKit -[UICollectionView _updateVisibleCellsNow:] + 2672 11 UIKit -[UICollectionView layoutSubviews] + 214 12 UIKit -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 258 13 QuartzCore -[CALayer layoutSublayers] + 214 14 QuartzCore CA::Layer::layout_if_needed(CA::Transaction*) + 460 15 QuartzCore CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 16 16 QuartzCore CA::Context::commit_transaction(CA::Transaction*) + 238 17 QuartzCore CA::Transaction::commit() + 316 18 QuartzCore CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 60 19 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 20 25 UIKit UIApplicationMain + 1120 26 MyApp main.m line 16 main Exception Type: EXC_BAD_ACCESS Code: KERN_INVALID_ADDRESS at 0x158848
What I'm doing in line 52 in setupBSCTopnewsCollectionView is
BSCInfiniteLayout *infiniteLayout = [[BSCInfiniteLayout alloc] init]; (line 52) self.collectionView.collectionViewLayout = infiniteLayout;
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
if([collectionView isEqual:self.collectionView])
{
if(indexPath.row == 0) // Header Cell
{
BSCTopnewsCollectionView *cell = [collectionView dequeueReusableCellWithReuseIdentifier:BSCHeaderReuseIdentifier forIndexPath:indexPath];
cell.dataSource = self;
cell.weakDelegatePointer = self;
self.topNewsCollectionView = cell;
return cell;
}
else
{
//create normal cells
}
}
else if ([collectionView isEqual:self.topNewsCollectionView.collectionView])
{
BSCTopNewsHeaderCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:BSCTopNewsCellReuseIdentifier forIndexPath:indexPath];
BSCNews *topnews = [self.topNews objectAtIndex:indexPath.row];
[cell setEntity:topnews];
return cell;
}
}
A few clarifications for the method calls there:
- (void)setWeakDelegatePointer:(BSCFrontPageViewController *)weakDelegatePointer
{
_weakDelegatePointer = weakDelegatePointer;
[self setupBSCTopnewsCollectionView];
[self.collectionView reloadData];
}
- (void)setupBSCTopnewsCollectionView
{
self.collectionView.delegate = self.weakDelegatePointer;
self.collectionView.dataSource = self.weakDelegatePointer;
BSCInfiniteLayout *infiniteLayout = [[BSCInfiniteLayout alloc] init];
infiniteLayout.delegate = self;
// Setup Layout
self.collectionView.collectionViewLayout = infiniteLayout;
self.collectionView.showsHorizontalScrollIndicator = NO;
self.collectionView.pagingEnabled = YES;
// Register Cells
[self.collectionView registerNib:[UINib nibWithNibName:@"BSCTopNewsHeaderCell" bundle:nil] forCellWithReuseIdentifier:BSCTopNewsCellReuseIdentifier];
}
If the CollectionView is reloaded while the app is running without being in the background in the beginning everything is fine.
Pulling our "Answer" out of the comments.
Sadly none of the answers helped. I ended up refactoring the whole thing and then the problem disappeared. I even had an pretty detailed talk with an apple DTS engineer who also didn't knew what to do. So we just refactored. Sorry :/