为什么tableView:cellForRowAtIndexPath:在后台线程上调用?
在我的iPhone应用程序中,偶尔会看到由tableView:cellForRowAtIndexPath引起的崩溃:在后台线程上调用。为什么tableView:cellForRowAtIndexPath:在后台线程上调用?
显然,这不应该发生。我没有要求它,我的目标是一个委托一个UITableView和基础呼唤它 - 我在堆栈中有问题的线程唯一看到的是
-_WebTryThreadLock(bool) -_dequeuReusableViewOfType -tableView:cellForRowAtIndexPath: -_createPreparedCellForGlobalRow:withIndexPath -_pthread_qathread
在WebTryThreadLock发生崩溃 - 无真的令人惊讶,它不是线程安全的,不应该从主线程中调用。
但我怎么弄清楚为什么我的tableView委托在背景线程上被调用?
我想知道 - 如果我在后台线程上调用[tableView reloadData],会这么做吗?
我一直认为它只是在主线程上调用调用而不管。我不确定我是否在做这件事,但我可能会这样做,而且我会检查一下,但是真的,不应该UIKit检查并在主线程上调用委托方法?
您不能在辅助线程上调用[tableView reloadData]
。你不能在辅助线程上调用任何UIKit的东西(除了一些例外,如UIImage
)。这包括所有tableView方法,包括直接获取者和设置者。它与渲染是否相关无关紧要。
这也是我的理解,谢谢您的确认。仔细检查我的代码后,我确信我不会那样做。但我会三重检查以确定三重。那么,你能想到任何可能导致调用cellForRowAtIndexPath的基础的(其他)场景:在bg线程上? – Jordan
@Jordan对于表视图有四种不同的'reload ...'方法,所以请确保你不要从后台线程中调用它们中的任何一个。还有'scrollTo ...'方法。也不要调用任何会改变你的表视图的框架,或者,例如,弹出一个你推到它上面的视图控制器等等。这些都是UIKit的东西,所以如果你确保你做了所有的UIKit调用主队列,你会没事的。 – Rob
“所以如果你确保你从主队列中完成所有的UIKit调用,你将会很好” - 是的,那也是我的想法。看起来我似乎有一些代码正在做这件事,但我还没有发现它! – Jordan
这可能是有趣的,撒些这些在你的视图控制器:(![NSThread isMainThread])
如果{ 的NSLog(@ “咦?”); }
我很确定UIKit/IOS不会决定在后台线程上调用表视图委托方法。你有没有dispatch_async,detachNewThreadSelector,performSelectorInBackground?
你可以发布详细的崩溃日志。另外,你是否包含任何第三方框架(任何)? –
你问,“不应该UIKit检查?”我可以理解你为什么要这么做,但简单的事实是它不会,你只需确保你的tableview相关调用在主队列中执行。 – Rob
发布您的代码和崩溃日志以获得更好的答案 – Jatin