I have been fighting with the following stack trace for the whole day. I'm unable to reproduce the issue but I know it happens for a large number of users (Crashlytics).
Crashed: com.apple.main-thread
EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x0000000000000010
Thread : Crashed: com.apple.main-thread
0 libobjc.A.dylib 0x0000000194187bd0 objc_msgSend + 16
1 UIKit 0x000000018860639c -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 544
2 UIKit 0x00000001885fafc4 -[UITableView _updateVisibleCellsNow:isRecursive:] + 2360
3 UIKit 0x00000001883f0c60 -[UITableView layoutSubviews] + 172
4 UIKit 0x000000018830d874 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 572
5 QuartzCore 0x0000000187c65d58 -[CALayer layoutSublayers] + 168
6 QuartzCore 0x0000000187c60944 CA::Layer::layout_if_needed(CA::Transaction*) + 320
7 QuartzCore 0x0000000187c607e8 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 32
8 QuartzCore 0x0000000187c5ffe8 CA::Context::commit_transaction(CA::Transaction*) + 276
9 QuartzCore 0x0000000187c5fd6c CA::Transaction::commit() + 436
10 UIKit 0x0000000188304848 _afterCACommitHandler + 156
11 CoreFoundation 0x0000000183b46388 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
12 CoreFoundation 0x0000000183b43314 __CFRunLoopDoObservers + 360
13 CoreFoundation 0x0000000183b436f4 __CFRunLoopRun + 836
...
This happens in a UIViewController who owns a UITableView. The view controller is also the data source and the delegate for the table view.
Looking at the stack trace, I was guessing that the view controller would be deallocated while some animation or slow operation was going on. After trying everything, I can't find a configuration where this would happen.
Would you have any suggestion on why a VC could be deallocated while one of its view is still animating?
I noticed that this crash coincides with switching from UITableViewController
to UIViewController
+ UITableView
.
Presumably, the UITableViewController
was nillifying the table view's delegate and datasource when it was deallocated. It wasn't the case with the new code.
To solve the issue, I set them to nil in - (void)dealloc
:
- (void)dealloc {
_tableView.dataSource = nil;
_tableView.delegate = nil;
}
The reason why they need to be set to nil is that both the UITableView's dataSource and delegate are unsafe_unretained references.
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