Question

In my iPhone app, I am occasionally seeing a crash caused by tableView:cellForRowAtIndexPath: being called on a background thread.

Obviously, this should not be happening. I'm not calling it, my object is a delegate to a UITableView and the foundation is calling it - the only thing I see in the stack for the thread in question is

-_WebTryThreadLock(bool)
-_dequeuReusableViewOfType
-tableView:cellForRowAtIndexPath:
-_createPreparedCellForGlobalRow:withIndexPath
-_pthread_qathread

The crash occurs in WebTryThreadLock - no surprise really, it's not threadsafe and should not be called off the main thread.

But how do I figure out WHY my tableView delegate is being called on a background thread?

I wonder - if I were to call [tableView reloadData] on a background thread, would that do it?

I always thought it would just dispatch the call on the main thread regardless. I'm not sure I am even doing that, but I might be, and I will check for that, but really, shouldn't UIKit check for that and call the delegate methods on the main thread anyway?

Was it helpful?

Solution

You can't call [tableView reloadData] on a secondary thread. You can't call any UIKit stuff on a secondary thread (with a few exceptions, such as UIImage). This includes all tableView methods, including straight getters and setters. It doesn't matter whether it is rendering related or not.

OTHER TIPS

It might be interesting to sprinkle some of these around your view controller:

if (![NSThread isMainThread]) { NSLog(@"Huh?"); }

I'm pretty sure UIKit/IOS would not decide on it's own to call a table view delegate method on a background thread. Do you have any dispatch_async, detachNewThreadSelector, performSelectorInBackground?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top