iOS多线程-NSURLSession和UI更新

iOS多线程-NSURLSession和UI更新,ios,multithreading,http,swift,grand-central-dispatch,Ios,Multithreading,Http,Swift,Grand Central Dispatch,我对iOS中的多线程有一个一般性问题: 在我非常简单的测试应用程序中,我使用NSURLSession从服务器下载一些小图像,并将它们显示在表视图中。在NSURLSession的回调中,检索图像后,我调用tableview.reloadData(),如下所示: 图像几乎是瞬间下载的,但是更新表视图需要10-20秒要明确的是,更新代理在10-20秒内甚至都不会被调用。但是,如果我将reloadData()放在主线程上,它会快速更新。像这样: var session = NSURLSession.sh

我对iOS中的多线程有一个一般性问题:

在我非常简单的测试应用程序中,我使用NSURLSession从服务器下载一些小图像,并将它们显示在表视图中。在NSURLSession的回调中,检索图像后,我调用tableview.reloadData(),如下所示:

图像几乎是瞬间下载的,但是更新表视图需要10-20秒要明确的是,更新代理在10-20秒内甚至都不会被调用。但是,如果我将reloadData()放在主线程上,它会快速更新。像这样:

var session = NSURLSession.sharedSession().dataTaskWithURL(NSURL(url)) {(data, response, error) -> Void in
    /* Process images here */
    dispatch_async(dispatch_get_main_queue()) {
        self.tableView.reloadData()
    }
} session.resume()
这样,我的问题就解决了,我又可以安心睡觉了。但谁能给我解释一下为什么会这样?我知道UI更新应该在主线程上执行——那么为什么第一个案例仍然有效,却要花很长时间呢?在应用程序中没有其他的事情发生,所以我甚至不能开始思考是什么让重新加载延迟了整整20秒。它是在等待NSURLSession首先完全关闭,还是沿着这些路线?寻找大素数?挖掘比特币


我对多线程的了解是有限的,因此对这种情况的任何了解都将非常有助于将来的参考。

除了main之外,我们不会在任何线程中更新UI,因为它会导致死锁。这里可能发生的情况是死锁持续10-20秒,然后有什么东西会释放死锁

并不是说在另一个线程上更新UI总是不起作用。你所经历的只是众多结果之一。我们真的不知道可可下面发生了什么,所以我们真的不知道

只要始终在主线程上更新UI,以避免类似的奇怪行为


您应该阅读这篇文章(特别是“线程和并发性”一段),Apple非常明确地指出,UI更新“必须”(而不仅仅是“应该”)在主线程上进行。当你做了他们警告你不要做的事情时,为什么它会做出这样的错误行为并不符合实际利益。我同意这是学术上的兴趣,但是它属于观点(或猜测)的范畴,因此,可能不属于这里。这在很大程度上是正确的,但我不相信你关于陷入僵局的猜测是正确的。尝试在主线程(或尝试更新UI的后台线程)上执行其他操作。它们都进行得非常愉快。
var session = NSURLSession.sharedSession().dataTaskWithURL(NSURL(url)) {(data, response, error) -> Void in
    /* Process images here */
    dispatch_async(dispatch_get_main_queue()) {
        self.tableView.reloadData()
    }
} session.resume()