【问题标题】:Loading images async in tableview在 tableview 中异步加载图像
【发布时间】:2021-02-09 15:10:00
【问题描述】:

我编写了一个异步方法来将图片加载到 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()
        }
    }
}

【问题讨论】:

    标签: swift xcode uitableview


    【解决方案1】:

    更新您的ImageLoader 代码,让您检查图像是否已在缓存中并同步返回给您。

    然后当你加载单元格时,如果它有图像,立即设置它。如果它没有图像,请让完成处理程序在该索引路径的单元格上重新加载。然后,由于图像现在被缓存,您的常规单元加载代码将能够填充图像。只需确保仅在尚未从缓存中设置图像时才请求图像。

    您的代码现在的编写方式,无论它是否在完成处理程序中从缓存中设置图像,它都会无休止地尝试重新加载它刚刚设置图像的行,这也会影响性能。因此,正如我所说,为什么您应该只在刚刚下载新图像时才重新加载单元格。并且不要在完成处理程序中设置图像,只需重新加载行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多