Я не могу заставить мой tableViewDataSourcePrefetching работать гладко с моими сетями и операциями.Я делаю что-то неправильно?Ниже приведены методы табличного представления.Я использую собственную ячейку.Используя Операцию, в которой я преобразую данные из URL-адресов изображений из Интернета (используя сеанс URL-адреса) и преобразую их в UIImage из данных и возвращаю их в закрытии завершения, а также присваиваю их переменной.
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)
}
}
Я пытаюсь использовать кеш ниже:
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()
}}
}
}
Вот операция, которую я использую в моем проекте:
class ImageLoadOperation: ConcurrentOperation {
var url: String
var completionHandler: ImageLoadOperationCompletionHandlerType
var image: UIImage?
init(url: String, completionHandler: ImageLoadOperationCompletionHandlerType) {
self.url = url
self.completionHandler = completionHandler
}
override func main() {
if isCancelled {
return
}
UIImage.downloadImageFromUrl(url) { [weak self] (image) in
guard let strongSelf = self,
!strongSelf.isCancelled,
let image = image else {
return
}
strongSelf.image = image
strongSelf.completionHandler?(image)
}
}
}