我试图将图像放入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
})
})
}
但我还有一些不清楚的事情:
NSURLConnection.sendAsynchronousRequest
正在后台执行任务,但NSOperationQueue.mainQueue()
似乎在主线程中执行任务(因为名称' mainQueue')。那真实的东西是什么?指令内的块是后台还是主线程?因为如果它在主线程上,则没有必要回到主线程来更新UI。
我听说NSURLConnection
用于快速请求。那是真的吗?因为当我使用NSURLSession
代替此异步NSURLConnection
请求下载所有单元格图片时,它会比NSURLConnection
更长。
那么我应该何时使用NSURLConnection
以及何时使用NSURLSession
? (例如:来自api的json数据或快速登录检查)
此外,当我退出应用程序时,系统缓存似乎正常。但是怎么样?因为我只将图像存储在数组中。那么为什么在关闭应用程序之后,它似乎总是被缓存?
答案 0 :(得分:1)
queue
参数指定运行完成块的队列,而不是将执行网络操作的队列。
顺便说一句,这意味着在完成块/闭包的当前实现中对主队列的附加调度是多余的。
请注意,有点令人惊讶的是,imageWithData
本身可以(特别是如果图像很大)运行时间超过几毫秒,这可能导致可观察到的(虽然非常轻微)口吃如果您在主线程中执行imageWithData
,则使用UI。通常你甚至不会注意到这一点,但是如果这个代码在表/集合视图中,如果快速滚动你就会看到它。因此,您可能希望使用除mainQueue
之外的操作队列作为网络请求的queue
参数,然后将调度最终UI更新的代码保留到主队列中。差异可能几乎不可察觉,但如果你想保持你的滚动丝滑顺畅,这是一个需要考虑的改进。它只取决于此代码出现的上下文。
NSURLSession
比NSURLConnection
更慢,这不是我的体验。我不知道(特别是没有看到NSURLSession
实现的代码),如果你的NSURLSession
实现由于某种原因没有缓存。
总法律顾问是,如果您需要支持7.0之前的iOS版本,请使用NSURLConnection
,否则请使用NSURLSession
。
您所看到的缓存是由NSURLConnection
和/或NSURLSession
透明提供的缓存,与您可能实际使用的任何应用级缓存完全分开你的阵列。