【发布时间】:2014-08-03 12:31:11
【问题描述】:
我正在尝试将图像放入 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? (例如:json 数据或来自 api 的快速登录检查) -
另外,当我退出应用程序时,系统缓存似乎有效。但是怎么做?因为我只是将图像存储在数组中。那么为什么关闭应用后,它似乎总是被缓存呢?
【问题讨论】:
-
顺便说一句,如果这是在表/集合视图中,请记住,您不能假设
cell在异步请求完成时仍然有效(因为单元格被重用)。通常,在dispatch_async块内,您将使用cellForXXXAtIndexPath查询表/集合视图(不要与视图控制器中类似命名的方法混淆)以查看单元格是否仍然可见,并使用新的用于更新图像的指针。 -
好的,那么调度外的单元格(在第一个 if 中),它可能是无效的?
-
第一个(你说
if image ...)很好,因为这是在cellForRowAtIndexPath的流程中同步发生的。但是异步请求中的任何内容(例如在sendAsynchronousRequest中)或dispatch_async中的任何内容都应该在尝试使用之前检查单元格是否仍然可见。如果您不这样做,尤其是在连接速度较慢的情况下,您可能会看到更新了错误的单元格(有时表现为单元格图像从一个到另一个闪烁)。
标签: ios multithreading background nsurlconnection nsurlsession