2016-09-18 49 views
3

我目前正在通过我的应用程序,更新它与Swift 3一起使用,并且还有一个问题。以前,我的图像缓存工作得很好,但是由于更新时UIImageView s没有被填充时图像被提取。Swift 3:在collectionView中缓存图像

这里是代码(在...cellForItemAt...功能):

if let img = imageCache[imageUrl] { 
    print("CACHE HIT: \(indexPath)") 
    cell.image.image = img 
} else { 
    print("CACHE MISS: \(indexPath)") 
    var imgUrl: = URL(string: imageUrl) 
    let request: URLRequest = URLRequest(url: imgUrl!) 
    let dataTask = session.dataTask(with: request, completionHandler: { (data, response, error) -> Void in 
     if(data != nil) { 
      print("IMAGE DOWNLOADED: \(imgUrl?.query))") 
      let image = UIImage(data: data!) // create the image from the data 
      self.imageCache[imageUrl] = image // Store in the cache 
      DispatchQueue.main.async(execute: { 
       if let cell = collectionView.cellForItem(at: indexPath) as? MyCollectionViewCell { 
        print("APPLYING IMAGE TO CELL: \(indexPath)") 
        cell.image.image = image 
        self.collectionView.reloadData() 
       } else { 
        print("CELL NOT FOUND: \(indexPath)") 
       } 
      }) 
     } 
    }) 
    dataTask.resume() 
} 

正如你所看到的,我已经在一些print增补找出到底是怎么回事。当视图加载时,我可以看到缓存未命中,以及为可见行填充图像加载和填充图像,但是当向下滚动时,UIImageViews永远不会填充,并且日志会为每个indexPath显示CELL NOT FOUND: [0, x]

如果在向下滚动后再次向上滚动,图像将按预期从缓存中填充。

自上一版本的Swift/iOS/Xcode以来,代码并没有改变,并且完美地工作。

我对任何第三方扩展等不感兴趣;我想了解上面的代码有什么问题。但是对代码的任何其他改进/建议都是受欢迎的。

任何想法将非常感激!

回答

2

而不是通过cellForItem(at: indexPath)方法获取单元格,只需使用cell变量来设置缓存命中中的图像。这将创建一个强烈的参考单元格的图像视图。

DispatchQueue.main.async(execute: { [weak collectionView] in 
    cell.image.image = image 
    collectionView?.reloadData() 
}) 

考虑重命名你UIImageViewimageView而非image

+0

感谢卡拉姆,这工作完美! '[weak self] in'如何帮助? – Ben

+1

如果您在闭包中引用自我,这将创建一个强有力的参考,并且这有时会导致问题。所以'[弱自己]'产生了一个会悄悄死去的弱点。 – Callam

+1

看看这个http://krakendev.io/blog/weak-and-unowned-references-in-swift – Callam