Crash in UITableView when animating cell changes while using estimatedHeightForHeaderInSection

Originator:mnachbaur
Number:rdar://24022858 Date Originated:29-Dec-2015 06:05 PM
Status:Open Resolved:
Product:iOS SDK Product Version:9.0
Classification:Crash/Hang/Data Loss Reproducible:Always
 
When tableView:estimatedHeightForHeaderInSection: is used when one of the table's sections have zero rows, and a cell animation (insertion, in my case) is performed in another section, the application will crash with an NSInvalidArgumentException within -[NSMutableArray insertObject:atIndex:] due to a nil value.

While troubleshooting the issue, I determined that the array of objects in question are the UITableViewCell instances that are going to participate in the animation in the -[UIView animateWithDuration:delay:options:animations:completion:] animation block.  While single-stepping the issue, the -[UITableView _updateWithItems:updateSupport:] method will interrogate the UITableViewDataSource for the cells during the update, but it only requests a few cells...certainly not enough to occupy the visible area of the screen.

Therefore, during the animation block, it doesn't request a cell from the data source, and it attempts to insert a nil value into the array.

If you either a) ensure that all sections have a minimum of 1 cell, or b) you don't use estimated section header heights, the crash will not occur.  I have attached a sample project that demonstrates the problem, with a set of instructions to demonstrate its use within the comments of ViewController.m in the zip file.

2015-12-29 17:57:07.391 TableViewCrash[42210:13929897] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:
(
	0   CoreFoundation                      0x0000000105f19e65 __exceptionPreprocess + 165
	1   libobjc.A.dylib                     0x0000000105990deb objc_exception_throw + 48
	2   CoreFoundation                      0x0000000105de08c5 -[__NSArrayM insertObject:atIndex:] + 901
	3   UIKit                               0x00000001063fb0ac __46-[UITableView _updateWithItems:updateSupport:]_block_invoke1027 + 180
	4   UIKit                               0x0000000106374370 +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 582
	5   UIKit                               0x00000001063747a5 +[UIView(UIViewAnimationWithBlocks) animateWithDuration:delay:options:animations:completion:] + 105
	6   UIKit                               0x00000001063facbb -[UITableView _updateWithItems:updateSupport:] + 4486
	7   UIKit                               0x00000001063f328a -[UITableView _endCellAnimationsWithContext:] + 15360
	8   TableViewCrash                      0x000000010548e466 -[ViewController setShowMoreCells:] + 486
	9   TableViewCrash                      0x000000010548de52 -[ViewController showMoreChanged:] + 482
	10  UIKit                               0x00000001062c9194 -[UIApplication sendAction:to:from:forEvent:] + 92
	11  UIKit                               0x00000001064386fc -[UIControl sendAction:to:forEvent:] + 67
	12  UIKit                               0x00000001064389c8 -[UIControl _sendActionsForEvents:withEvent:] + 311
	13  UIKit                               0x000000010665c0f6 -[_UISwitchInternalViewNeueStyle1 _setPressed:on:animated:shouldAnimateLabels:completion:] + 224
	14  UIKit                               0x000000010665d169 -[UISwitch _handleLongPressNL:] + 452
	15  UIKit                               0x00000001067afe73 _UIGestureRecognizerSendTargetActions + 153
	16  UIKit                               0x00000001067ac4e5 _UIGestureRecognizerSendActions + 162
	17  UIKit                               0x00000001067aa4e2 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 843
	18  UIKit                               0x00000001067b29a0 ___UIGestureRecognizerUpdate_block_invoke904 + 79
	19  UIKit                               0x00000001067b283e _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 342
	20  UIKit                               0x00000001067a0101 _UIGestureRecognizerUpdate + 2634
	21  UIKit                               0x0000000106337f8a -[UIWindow _sendGesturesForEvent:] + 1137
	22  UIKit                               0x00000001063391c0 -[UIWindow sendEvent:] + 849
	23  UIKit                               0x00000001062e7b66 -[UIApplication sendEvent:] + 263
	24  UIKit                               0x00000001062c1d97 _UIApplicationHandleEventQueue + 6844
	25  CoreFoundation                      0x0000000105e45a31 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
	26  CoreFoundation                      0x0000000105e3b95c __CFRunLoopDoSources0 + 556
	27  CoreFoundation                      0x0000000105e3ae13 __CFRunLoopRun + 867
	28  CoreFoundation                      0x0000000105e3a828 CFRunLoopRunSpecific + 488
	29  GraphicsServices                    0x000000010970fad2 GSEventRunModal + 161
	30  UIKit                               0x00000001062c7610 UIApplicationMain + 171
	31  TableViewCrash                      0x000000010548e7ef main + 111
	32  libdyld.dylib                       0x000000010866d92d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!