2013-07-05 59 views
3

在我的iPhone应用程序中,偶尔会看到由tableView:cellForRowAtIndexPath引起的崩溃:在后台线程上调用。为什么tableView:cellForRowAtIndexPath:在后台线程上调用?

显然,这不应该发生。我没有要求它,我的目标是一个委托一个UITableView和基础呼唤它 - 我在堆栈中有问题的线程唯一看到的是

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

在WebTryThreadLock发生崩溃 - 无真的令人惊讶,它不是线程安全的,不应该从主线程中调用。

但我怎么弄清楚为什么我的tableView委托在背景线程上被调用?

我想知道 - 如果我在后台线程上调用[tableView reloadData],会这么做吗?

我一直认为它只是在主线程上调用调用而不管。我不确定我是否在做这件事,但我可能会这样做,而且我会检查一下,但是真的,不应该UIKit检查并在主线程上调用委托方法?

+0

你可以发布详细的崩溃日志。另外,你是否包含任何第三方框架(任何)? –

+1

你问,“不应该UIKit检查?”我可以理解你为什么要这么做,但简单的事实是它不会,你只需确保你的tableview相关调用在主队列中执行。 – Rob

+0

发布您的代码和崩溃日志以获得更好的答案 – Jatin

回答

3

您不能在辅助线程上调用[tableView reloadData]。你不能在辅助线程上调用任何UIKit的东西(除了一些例外,如UIImage)。这包括所有tableView方法,包括直接获取者和设置者。它与渲染是否相关无关紧要。

+0

这也是我的理解,谢谢您的确认。仔细检查我的代码后,我确信我不会那样做。但我会三重检查以确定三重。那么,你能想到任何可能导致调用cellForRowAtIndexPath的基础的(其他)场景:在bg线程上? – Jordan

+2

@Jordan对于表视图有四种不同的'reload ...'方法,所以请确保你不要从后台线程中调用它们中的任何一个。还有'scrollTo ...'方法。也不要调用任何会改变你的表视图的框架,或者,例如,弹出一个你推到它上面的视图控制器等等。这些都是UIKit的东西,所以如果你确保你做了所有的UIKit调用主队列,你会没事的。 – Rob

+1

“所以如果你确保你从主队列中完成所有的UIKit调用,你将会很好” - 是的,那也是我的想法。看起来我似乎有一些代码正在做这件事,但我还没有发现它! – Jordan

2

这可能是有趣的,撒些这些在你的视图控制器:(![NSThread isMainThread])

如果{ 的NSLog(@ “咦?”); }

我很确定UIKit/IOS不会决定在后台线程上调用表视图委托方法。你有没有dispatch_async,detachNewThreadSelector,performSelectorInBackground?

+0

>很确定UIKit/IOS不会决定在后台线程上调用一个> table view委托方法 - 是的,这也是我的信念,到目前为止,我没有理由相信。 – Jordan

+0

我正在检查isMainThread,我可以在任何地方进行堆栈转储,并且在我发现我处于错误线程的地方进行堆栈转储,希望了解我是如何到达那里的。 – Jordan

+0

+1 ....呃? –

相关问题