微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 tableview 中异步加载图像

如何解决在 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 举报,一经查实,本站将立刻删除。