网络iOS:背景/ MainThread?

时间:2014-08-03 12:31:11

标签: ios multithreading background nsurlconnection nsurlsession

我试图将图像放入cell.image中。 如果图像已经加载(在缓存中),我就这样做了。否则,我使用sendAsynchronousRequest在后​​台下载。

这是我的代码:

var image = self.imageCached[urlString] as? UIImage

    if image {
        cell.imageView.image = image

    } else {

        let request = NSURLRequest(URL: NSURL(string: urlString))
        NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), { response, data, error -> Void in

            image = UIImage(data: data)
            self.imageCached[urlString] = image;

            dispatch_async(dispatch_get_main_queue(), {
                cell.imageView.image = image
            })
        })
    }

但我还有一些不清楚的事情:

  1. NSURLConnection.sendAsynchronousRequest正在后台执行任务,但NSOperationQueue.mainQueue()似乎在主线程中执行任务(因为名称' mainQueue')。那真实的东西是什么?指令内的块是后台还是主线程?因为如果它在主线程上,则没有必要回到主线程来更新UI。

  2. 我听说NSURLConnection用于快速请求。那是真的吗?因为当我使用NSURLSession代替此异步NSURLConnection请求下载所有单元格图片时,它会比NSURLConnection更长。

    那么我应该何时使用NSURLConnection以及何时使用NSURLSession? (例如:来自api的json数据或快速登录检查)

  3. 此外,当我退出应用程序时,系统缓存似乎正常。但是怎么样?因为我只将图像存储在数组中。那么为什么在关闭应用程序之后,它似乎总是被缓存?

1 个答案:

答案 0 :(得分:1)

  1. queue参数指定运行完成块的队列,而不是将执行网络操作的队列。

    顺便说一句,这意味着在完成块/闭包的当前实现中对主队列的附加调度是多余的。

    请注意,有点令人惊讶的是,imageWithData本身可以(特别是如果图像很大)运行时间超过几毫秒,这可能导致可观察到的(虽然非常轻微)口吃如果您在主线程中执行imageWithData,则使用UI。通常你甚至不会注意到这一点,但是如果这个代码在表/集合视图中,如果快速滚动你就会看到它。因此,您可能希望使用除mainQueue之外的操作队列作为网络请求的queue参数,然后将调度最终UI更新的代码保留到主队列中。差异可能几乎不可察觉,但如果你想保持你的滚动丝滑顺畅,这是一个需要考虑的改进。它只取决于此代码出现的上下文。

  2. NSURLSessionNSURLConnection更慢,这不是我的体验。我不知道(特别是没有看到NSURLSession实现的代码),如果你的NSURLSession实现由于某种原因没有缓存。

    总法律顾问是,如果您需要支持7.0之前的iOS版本,请使用NSURLConnection,否则请使用NSURLSession

  3. 您所看到的缓存是由NSURLConnection和/或NSURLSession透明提供的缓存,与您可能实际使用的任何应用级缓存完全分开你的阵列。