Iglistkit: [IGListAdapterUpdater performBatchUpdatesWithCollectionView:]

Created on 14 Dec 2017  路  16Comments  路  Source: Instagram/IGListKit

New issue checklist

General information

  • IGListKit version: 3.1.1
  • iOS version(s): 11.1.2; 11.2
  • Xcode version: 9.1
  • Devices/Simulators affected: iPhone 6; 6s; 7; 8;

Debug information

# 
Exception Type:  SIGABRT
Exception Codes: #0 at 0x184e8d348
Crashed Thread:  0

Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSDictionaryM setObject:forKey:]: key cannot be nil'

Last Exception Backtrace:
0   CoreFoundation                       0x0000000185375d04 __exceptionPreprocess + 124
1   libobjc.A.dylib                      0x00000001845c4528 objc_exception_throw + 52
2   CoreFoundation                       0x000000018530ebd4 _CFThrowFormattedException + 108
3   CoreFoundation                       0x0000000185243e48 -[__NSDictionaryM setObject:forKey:] + 892
4   UIKit                                0x000000018f2329cc -[UICollectionView _setVisibleView:forLayoutAttributes:] + 180
5   UIKit                                0x000000018f243620 __71-[UICollectionView _updateWithItems:tentativelyForReordering:animator:]_block_invoke.1997 + 744
6   UIKit                                0x000000018e7e19bc +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 616
7   UIKit                                0x000000018e7f81ac +[UIView(UIViewAnimationWithBlocks) animateWithDuration:delay:options:animations:completion:] + 104
8   UIKit                                0x000000018f242b04 -[UICollectionView _updateWithItems:tentativelyForReordering:animator:] + 5192
9   UIKit                                0x000000018f2403a8 -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:] + 13596
10  UIKit                                0x000000018f243d28 -[UICollectionView _endUpdatesWithInvalidationContext:tentativelyForReordering:animator:] + 88
11  UIKit                                0x000000018f24400c -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:animator:] + 384
12  UIKit                                0x000000018f243e68 -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:] + 92
13  UIKit                                0x000000018f243dec -[UICollectionView _performBatchUpdates:completion:invalidationContext:] + 80
14  UIKit                                0x000000018e969eb4 -[UICollectionView performBatchUpdates:completion:] + 60
15  IGListKit                            0x0000000101f53ee4 __62-[IGListAdapterUpdater performBatchUpdatesWithCollectionView:]_block_invoke.97 (IGListAdapterUpdater.m:229)
16  IGListKit                            0x0000000101f5336c -[IGListAdapterUpdater performBatchUpdatesWithCollectionView:] (IGListAdapterUpdater.m:262)
17  IGListKit                            0x0000000101f5526c __54-[IGListAdapterUpdater queueUpdateWithCollectionView:]_block_invoke (IGListAdapterUpdater.m:0)
18  libdispatch.dylib                    0x0000000184cf9088 _dispatch_call_block_and_release + 20
19  libdispatch.dylib                    0x0000000184cf9048 _dispatch_client_callout + 12
20  libdispatch.dylib                    0x0000000184d05b74 _dispatch_main_queue_callback_4CF$VARIANT$mp + 1012
21  CoreFoundation                       0x000000018531deb0 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
22  CoreFoundation                       0x000000018531ba8c __CFRunLoopRun + 2008
23  CoreFoundation                       0x000000018523bfb8 CFRunLoopRunSpecific + 432
24  GraphicsServices                     0x00000001870d3f84 GSEventRunModal + 96
25  UIKit                                0x000000018e8102e8 UIApplicationMain + 204
26  MyApp                                0x00000001008e04f0 main (main.swift:30)
27  libdyld.dylib                        0x0000000184d5e56c start + 0
missing-info question

Most helpful comment

okay after further debugging it seems you need to invalidate the layout for the supplemntary view, I do this just through [[[self collectionView] collectionViewLayout] invalidateLayout];, as if you don't when it goes to reload the supplemtary attributes for the footer that returns CGSizeZero in the referenceSize function it won't have attributes and therefore crash the program

All 16 comments

Hi! @rnystrom can you help me with this error? Thank you very much!

Can you make a reproducible project or maybe run po [IGListDebugger dump] as requested in the ISSUE template? This will assist in finding out what's going wrong in this case.

@aortegas this will be impossible to debug without more info. A sample project would be great. It looks like an issue with a layout using nil attributes? What type of layout are you using?

Sent with GitHawk

Thank you very much for your responses.

We haven't been able reproduce this bug in develop. We found the trace of this problem in production using hockey app, but we dont know anything else, just that we have this problem with our users several times.

We use IGListKit in several sites of our app, and we dont know in which of them this problem occurs... we dont know how it's produced either.

We are using UICollectionViewFlowLayout configured this way:

private lazy var flowLayout: UICollectionViewFlowLayout = {
var layout = UICollectionViewFlowLayout()
layout.minimumInteritemSpacing = 1.0
layout.minimumLineSpacing = 1.0
return layout
}()

In the rest of cases, we are using only: UICollectionViewFlowLayout()

Maybe, you kwow (for other similars problem) witch the reason or give us any info to solve this problem in our app.

Thanks!

Hey I'm having the same issue with some other thing, if I find out why this happens I will be sure to let you know what the possible cause might be

this crash will stem from the passed layoutAttributes object for the method part of the signature forLayoutAttributes: returning nil for the selector __indexPath, the selector __indexPath just grabs the ivar "_indexPath" on the layoutAttributes Object

@aortegas are you using any supplementary views in any of your collections where this could possible be happening?

Okay so in my expercience this seems to happen when you return CGSizeZero for a supplementary view when it was previously not CGSizeZero and this change happens inside the performBatchUpdates block

okay after further debugging it seems you need to invalidate the layout for the supplemntary view, I do this just through [[[self collectionView] collectionViewLayout] invalidateLayout];, as if you don't when it goes to reload the supplemtary attributes for the footer that returns CGSizeZero in the referenceSize function it won't have attributes and therefore crash the program

@andrewwiik Thank you very much for your help!

I will verify my code, to make the necessary changes, follow your comments.
I will continue reporting on it. Thank you very much again.

@aortegas Have you figured out your issue yet?

I got a chance to reproduce this locally, so my problem is that I am returning a nil UICollectionLayoutAttributes when implementing the

override func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes?

Even thought Apple document saying that we can return an optional UICollectionViewLayoutAttributes, but I got that weird "key is nil" error because of the nil indexPath of the layoutAttributes that it's asking for.

I suggest that you put break point on all those override UICollectionViewLayout methods, and debug and see where nil/edge case happens. Hope this helps.

@andrewwiik you saved my day

I have this too, but I'm not using a custom layout, and calling invalidateLayout had no effect :(
The only thing I can tell so far is that it is indeed related to supplementary views: once I remove them, the crash stops.
Adding to the OP, besides iOS 11 this crash was also reported on iOS 9 & 10 in our app.

edit: I was using IGListKit 3.1.1 - in 3.3 I can't reproduce it anymore. Possibly related to https://github.com/Instagram/IGListKit/commit/d9a89c9b00aa1a9537a24d9affb6919f83065f65

I had the same issue and it was fixed by invalidating collectionViewLayout before reloading the adapter.

according to the documentation of performBatchUpdates:

If the collection view's layout is not up to date before you call this method, a reload may occur. To avoid problems, you should update your data model inside the updates block _or_ ensure the layout is updated before you call performBatchUpdates(_:completion:).

But there is also a bug in UICollectionView that makes it crash when you try to remove a supplementary view in performBatchUpdates: https://openradar.appspot.com/radar?id=4929160833138688

Was this page helpful?
0 / 5 - 0 ratings