我需要执行这种情况:
URLSessionDataTask
)。URLSessionDownloadTask
作为我获得的图片网址),然后将其显示在UITableView
(每个单元格一个图像)。此外,对于数据任务(初始搜索),我使用URLSessionConfiguration.default
,对于多个下载任务,我使用URLSessionConfiguration.background
。
初始搜索(数据任务)和设置N图像下载(N个下载任务)是串行的,这意味着我需要获得初始搜索的响应以启动图像下载。但是我需要将N个图像下载并发,因为一旦某个图像完成下载,我将在相应的单元格中显示每个图像。
另一方面,所有这些网络操作(搜索+下载)当然都需要是异步的。
我的问题:我看到URLSession
有一个初始化程序,可以提供OperationQueue
作为delegateQueue
参数。关于这个选项,我想我应该这样做:
self.queue = OperationQueue()
self.queue.qualityOfService = .userInitiated
self.defaultSession = URLSession(configuration: configuration, delegate: nil, delegateQueue: queue)
self.backgroundSession = URLSession(configuration: backgroundConfiguration, delegate: self, delegateQueue: queue)
然后,当用户开始新搜索时,我应该可以致电self.queue.cancelAllOperations()
。
这是我的方案的正确方法吗?图像会同时下载吗?
我考虑的另一个选项是创建相同的OperationQueue
,但不是将其作为delegateQueue
传递给URLSession
,而是将数据任务和下载任务建模为Operation
并致电self.queue.addOperation
。
这两个选项之间的行为和表现有什么不同吗?哪一个应该适合我的场景?或者更好的是一种不同的方法(在这种情况下,哪一种方法)?
修改
我想到的其他选项是:每个单元都有一个对自己的URLSessionDownloadTask
的引用,并在重用单元格时调用下载其图像,但在新的下载时要取消该任务执行,类似的事情:
var downloadTask: URLSessionDownloadTask?
func downloadImage(imageUrl: URL) {
downloadTask?.cancel()
let request = URLRequest(url: url)
downloadTask = backgroundSession.downloadTask(with: request)
downloadTask?.resume()
}
这里我没有使用操作队列,只是取消任务。这是正确和更好的选择吗?我应该在单元格出列时调用downladTask?.cancel()
吗?