我似乎无法通过网络和Operation使tableViewDataSourcePrefetching顺利运行。难道我做错了什么?下面是表格视图方法。我也使用自定义单元格。在我要从Web的图像url转换数据(使用url会话)并将其从数据转换为UIImage的操作中,并在完成闭包中将其返回以及将其分配给变量。
n >= 3
我正在尝试使用下面的缓存:
let cell = tableView.dequeueReusableCell(withIdentifier: "ImageCell", for: indexPath) as! ImageTableViewCell
if let imagesModel = imageController.viewModel(at: indexPath.row) {
cell.images = imagesModel
if let imageLoadOperation = imageLoadOperations[indexPath],
let image = imageLoadOperation.image {
cell.picImageView.image = image
} else {
let imageLoadOperation = ImageLoadOperation(url: imagesModel.downloadUrl, completionHandler: { [weak self] (image) in
guard let strongSelf = self else {
return
}
DispatchQueue.main.async {
cell.picImageView.image = image
}
strongSelf.imageLoadOperations.removeValue(forKey: indexPath)
})
imageLoadQueue.addOperation(imageLoadOperation)
imageLoadOperations[indexPath] = imageLoadOperation
}
}
return cell
}
override func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let imageLoadOperation = imageLoadOperations[indexPath] else {
return
}
imageLoadOperation.cancel()
imageLoadOperations.removeValue(forKey: indexPath)
}
}
extension ImagesTableViewController: UITableViewDataSourcePrefetching {
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
for indexPath in indexPaths {
if let _ = imageLoadOperations[indexPath] {
return
}
if let viewModel = imageController.viewModel(at: (indexPath as NSIndexPath).row) {
let imageLoadOperation = ImageLoadOperation(url: viewModel.downloadUrl, completionHandler: {(image) in
})
imageLoadQueue.addOperation(imageLoadOperation)
imageLoadOperations[indexPath] = imageLoadOperation
}
}
}
func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) {
for indexPath in indexPaths {
guard let imageLoadOperation = imageLoadOperations[indexPath] else {
return
}
imageLoadOperation.cancel()
imageLoadOperations.removeValue(forKey: indexPath)
}
}
这是我的项目中使用的Operation im:
static func downloadImageFromUrl(_ url: String, completionHandler: @escaping (UIImage?) -> Void) {
guard let url = URL(string: url) else {
completionHandler(nil)
return
}
let cache = URLCache.shared
let request = URLRequest(url: url)
DispatchQueue.global(qos: .userInitiated).async {
if let data = cache.cachedResponse(for: request)?.data, let image = UIImage(data: data) {
DispatchQueue.main.async {
completionHandler(image)
}
} else {
let task: URLSessionDataTask = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) -> Void in
guard let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
let data = data, error == nil,
let image = UIImage(data: data) else {
completionHandler(nil)
return
}
let cachedData = CachedURLResponse(response: response!, data: data)
cache.storeCachedResponse(cachedData, for: request)
completionHandler(image)
})
task.resume()
}}
}
}