如何解决在 tableview 中异步加载图像
我编写了一个异步方法来将图片加载到 tableview 中。但问题是图像没有加载,因为它不会在滚动后自动更新。我尝试添加:
tableView.reloadRows(at: [indexPath],with: UITableView.RowAnimation.none)
但这只会用不同的图像一直刷新行。第二个问题是,滚动后会显示图片,但有时图片会加载到错误的行中。
请有人帮我解决这个问题,因为我无法弄清楚。
override func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ArticleCell",for: indexPath)
let article = newsArticles!.articles[indexPath.row]
cell.textLabel?.text = article.title
cell.detailTextLabel?.text = article.content
cell.imageView?.image = nil
if let url = article.urlToImage {
imageLoader.obtainImageWithPath(imagePath: url) { (image) in
if let updateCell = tableView.cellForRow(at: indexPath) {
updateCell.imageView?.image = image
tableView.reloadRows(at: [indexPath],with: UITableView.RowAnimation.none)
}
}
}
return cell
}
图像加载器:
class ImageLoader {
var imageCache = NSCache<Nsstring,UIImage>()
init() {
self.imageCache = NSCache()
}
func obtainImageWithPath(imagePath: URL,completionHandler: @escaping (UIImage) -> ()) {
if let image = self.imageCache.object(forKey: imagePath.absoluteString as Nsstring) {
dispatchQueue.main.async {
completionHandler(image)
}
} else {
let placeholder: UIImage = UIImage(named: "placeholderImage")!
dispatchQueue.main.async {
completionHandler(placeholder)
}
let task = URLSession.shared.dataTask(with: imagePath,completionHandler: {data,response,error in
let image: UIImage! = UIImage(data: data!)
self.imageCache.setobject(image,forKey: imagePath.absoluteString as Nsstring)
dispatchQueue.main.async {
completionHandler(image)
}
})
task.resume()
}
}
}
解决方法
更新您的 ImageLoader
代码,让您检查图像是否已在缓存中并将其同步返回给您。
然后当你加载单元格时,如果它有图像,立即设置它。如果它没有图像,则让完成处理程序在该索引路径的单元格上重新加载。然后,由于图像现在已缓存,您的常规单元格加载代码将能够填充图像。只要确保您只请求尚未从缓存中设置的图像。
您的代码现在的编写方式,无论是否在完成处理程序中设置缓存中的图像,它都会无休止地尝试重新加载刚刚设置图像的行,这也会影响性能。这就是为什么,正如我所说的,如果刚刚下载了新图像,您应该只重新加载单元格。并且不要在完成处理程序中设置图像,只需重新加载行。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。