Iglistkit: UICollectionView dealloc cause crash issue when using method `invalidateLayout `

Created on 14 Mar 2018  路  6Comments  路  Source: Instagram/IGListKit

General information

  • IGListKit version: 3.2.0
  • iOS version(s): 11.2
  • CocoaPods/Carthage version: 1.4.0
  • Xcode version: 9.2
  • Devices/Simulators affected: All
  • Reproducible in the demo project? (Yes/No): YES
  • Related issues: #929, #930, #931

Debug information

I am trying to implement a form with IGListKit, but face a crash issue.

The main goal of the project is trying to own several viewModel and binding the value from a cell's textView.

Two way will calculate cell height:

  1. When the textView's value change, notify sectionController, and recalculate the cell's height.
  2. Calculate cell height is in method cellForItem(at index:). (Doing this because of dynamic cell heihgt.)

If the cell's height not equal to previous value, sectionController invoke invalidateLayout(for:completion:) method to refresh collectionViewCell.

Everything work well until using adapter's method reloadData(completion:) and async viewModels provider.

The viewModels be created by async (In real case is network, using GCD to reproduce same situation), when viewModels updated, notify adapter to reload the data.

Crash

If I back to previous page immediately, the crash happend. But if I scroll collectionView and back, nothing happed.

stack trace:

2018-03-14 15:25:01.655976+0800 IGListKitCrashBug[66037:46027071] [general] Caught exception during autorelease pool drain NSInternalInconsistencyException: UICollectionView (<UICollectionView: 0x7f863e856000; frame = (0 0; 320 568); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x60800024f420>; layer = <CALayer: 0x60800003f060>; contentOffset: {0, -64}; contentSize: {320, 2450.5}; adjustedContentInset: {64, 0, 0, 0}> collection view layout: <IGListCollectionViewLayout: 0x7f863e500f70>) was deallocated while an update was in flight userInfo: (null)
2018-03-14 15:25:01.669900+0800 IGListKitCrashBug[66037:46027071] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView (<UICollectionView: 0x7f863e856000; frame = (0 0; 320 568); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x60800024f420>; layer = <CALayer: 0x60800003f060>; contentOffset: {0, -64}; contentSize: {320, 2450.5}; adjustedContentInset: {64, 0, 0, 0}> collection view layout: <IGListCollectionViewLayout: 0x7f863e500f70>) was deallocated while an update was in flight'
*** First throw call stack:
(
    0   CoreFoundation                      0x00000001060d712b __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x0000000102a07f41 objc_exception_throw + 48
    2   CoreFoundation                      0x00000001060dc2f2 +[NSException raise:format:arguments:] + 98
    3   Foundation                          0x00000001024a8d69 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 193
    4   UIKit                               0x0000000103d6d8f4 -[UICollectionView dealloc] + 771
    5   libobjc.A.dylib                     0x0000000102a1d178 _ZN12_GLOBAL__N_119AutoreleasePoolPage3popEPv + 860
    6   UIKit                               0x000000010334497f -[UIView dealloc] + 1044
    7   libobjc.A.dylib                     0x0000000102a1d178 _ZN12_GLOBAL__N_119AutoreleasePoolPage3popEPv + 860
    8   CoreFoundation                      0x00000001060213f6 _CFAutoreleasePoolPop + 22
    9   CoreFoundation                      0x000000010605e46a __CFRunLoopRun + 2410
    10  CoreFoundation                      0x000000010605d889 CFRunLoopRunSpecific + 409
    11  GraphicsServices                    0x00000001086e59c6 GSEventRunModal + 62
    12  UIKit                               0x00000001032a45d6 UIApplicationMain + 159
    13  IGListKitCrashBug                   0x000000010200b4c7 main + 55
    14  libdyld.dylib                       0x0000000107079d81 start + 1
    15  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Question

  1. I'm not sure can I used invalidateLayout(for:completion:) method in cellForItem(at index:) when the height change?
  2. If I can't, what is the best practice in my case?

My solution

I'm trying to calculate the cell height in sizeForItem(at index:) method and allocate a cell by myself to calculate the size.
No using invalidateLayout(for:completion:) in cellForItem(at index:) and the crash go away.

Although solve my problem, I still want to know do and don't when using invalidateLayout(for:completion:), reloadData(completion:) and performUpdates(animated, completion:) methods.

question

All 6 comments

BTW, only first cell's height different with other cells cause crash but I don't know why.

Any time I鈥檝e run into this it鈥檚 because there is a retain cycle keeping the collection view around. Can you try using the memory debug tool to see if there are any cycles?

Sent with GitHawk

2018-03-16 9 00 36
2018-03-16 9 07 31

Not sure any retain cycle happened, but I think not.
If need more info about this, please tell me, thanks for your help. 馃榾

This is demo project: Demo

@marcuswu0814 thanks for the example! The problem here is you're calling

self.collectionContext?.invalidateLayout(for: self, completion: nil)

Inside cellForItem(at index:). If you uncomment this line it works (obviously not updating your height correctly). IMO you need another design for updating the cell heights, it seems like UICollectionView is getting internal state corrupted by invalidating the layout when dequeuing cells.

Really thanks. @rnystrom 馃槃
I solve this problem in solution branch and working well now, if someone need to implement the feature like this. (Dynamic height cell with text view input and calculate cell鈥檚 height using autoLayout) Just take a look. 馃槄

Sent with GitHawk

I'll think about adding an assert to the invalidate method so that if you call it from w/in a cell dequeue that it let's you know things will probably break. Great question though, and really appreciate you providing a demo project! Makes it easy for me to help out 馃槃

Was this page helpful?
0 / 5 - 0 ratings

Related issues

drinkius picture drinkius  路  3Comments

rnystrom picture rnystrom  路  3Comments

alexwillrock picture alexwillrock  路  3Comments

runmad picture runmad  路  3Comments

rnystrom picture rnystrom  路  3Comments