Swift UITableViewCell-如果向下滚动过快,单元格图像会发生更改,但仅在第一次尝试时发生

Swift UITableViewCell-如果向下滚动过快,单元格图像会发生更改,但仅在第一次尝试时发生,swift,uitableview,Swift,Uitableview,我正在分析viewDidLoad方法中的JSON。这个JSON中的一个键是图像URL,它进入一个名为“allCImages”的字符串数组 这只是一根线。因此,要将图像填充到单元格中,在我的cellForRowAt方法中,我有以下内容: cell.vcCellImage.downloadImage(from: allCImages[indexPath.section]) 注意:vcCellImage是“我的手机图像”视图的IBOutlet “downloadImage”方法是以下扩展的一部分:

我正在分析viewDidLoad方法中的JSON。这个JSON中的一个键是图像URL,它进入一个名为“allCImages”的字符串数组

这只是一根线。因此,要将图像填充到单元格中,在我的cellForRowAt方法中,我有以下内容:

cell.vcCellImage.downloadImage(from: allCImages[indexPath.section])
注意:vcCellImage是“我的手机图像”视图的IBOutlet

“downloadImage”方法是以下扩展的一部分:

extension UIImageView {
    func downloadImage(from imgURL: String!) {
        let theUrl = URLRequest(url: URL(string: imgURL)!)

        // set initial image to nil so it doesn't use the image from a reused cell
        image = nil

        // check if the image is already in the cache
        if let imageToCache = vc1ImageCache.object(forKey: imgURL! as NSString) {
            self.image = imageToCache
            print("Image is in Cache")
            return
        }

        // download the image asynchronously 
        let task = URLSession.shared.dataTask(with: theUrl) { (data, response, error) in
            if error != nil {
                print(error!)
                return
            }

            DispatchQueue.main.async {
                // create UIImage
                let imageToCache = UIImage(data: data!)
                // add image to cache
                vc1ImageCache.setObject(imageToCache!, forKey: imgURL! as NSString)
                self.image = imageToCache
            }
        }

        task.resume()
    }
这几乎是完美的工作。例如:

1) 如果我慢慢向下滚动tableview,所有单元格都包含正确的图像

2) 如果我缓慢或快速地向上滚动tableview,所有单元格都包含正确的图像。我的控制台正在打印以下内容,这一事实证明了这一点:

cell.vcCellImage.downloadImage(from: allCImages[indexPath.section])
  • 图像在缓存中
  • 图像在缓存中
  • 图像在缓存中
也就是说,tableview正在从缓存中获取我的图像(因为要向上滚动,我之前必须向下滚动)

3) 问题是如果我在第一次尝试时快速向下滚动我的tableview。由于图像尚未缓存,单元格将在更改为正确的图像之前显示错误的图像。经典问题

因此,我遗漏了这一小部分逻辑。如何解决这个问题



编辑:我尝试过,但问题仍然存在:

  • VCTableViewCell类:UITableViewCell{

    重写func prepareForReuse()函数{ super.prepareforeuse() vcCellImage.image=nil }


    • 我也遇到过类似的问题。 我已通过取消prepareforeuse方法中的图像请求解决了此问题。
      你能试试同样的方法吗?

      这是因为

      1-单元出列:在tableView中重复使用单元

      2-当您在请求发生前滚动时,可能会导致具有相同url的新1


      最好的选择是首先使用

      ,如果您要附加api或类似的任何数据,请删除它

      var arr = [string]()
      
      viewDidLoad()
      {
      arr.append("s","sd","sd)
      }
      
      接受这个

      var arr = [string]()
      
      viewWillAppear()
      {
      arr.removeAll()
      //call api
      //append Data
      arr.append("s","sd","sd)
      }
      

      我有类似的问题,然后我这样解决,可能对您也有帮助。

      我尝试了这个方法,但问题仍然存在:-类VCTableViewCell:UITableViewCell{override func prepareforuse(){super.prepareforuse()vcCellImage.image=nil}hey@SteveJobs将image设置为nil不起作用。您需要取消URLRequest。在这里,您可以在VCTableViewCell中创建一个任务URLSession任务变量,并存储每个相应单元格的任务,然后在prepare for resuse do task中。cancel()