Swift 3:在collectionView中缓存图片

4

我目前正在更新我的应用程序,使其与Swift 3兼容,并且还有一个问题需要解决。之前,我的图像缓存非常有效,但自从更新以来,当获取图像时UIImageView未被填充。

这是代码(在...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来确定发生了什么。当视图加载时,我可以看到缓存未命中,并且图像正在加载以及可见行的UIImageView被填充,但是当我向下滚动时,UIImageView从未被填充,并且日志显示对于每个indexPath,“CELL NOT FOUND:[0,x]”。
如果我在向下滚动后再向上滚动,则预期会从缓存中填充图像。
代码自上一个版本的Swift / iOS / Xcode以来没有更改,之前完美地工作。
我不关心任何第三方扩展等;我想了解上述代码有什么问题。但是,欢迎提出任何其他的改进/建议。
非常感谢您的任何想法!
1个回答

2

不要通过cellForItem(at: indexPath)方法获取单元格,只需使用设置缓存中图像的cell变量即可。这将创建对单元格图像视图的强引用。

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

考虑将你的UIImageView重命名为imageView而不是image


谢谢 Callam,那个完美地解决了! [weak self] in 如何帮助? - Ben
1
如果在闭包中引用self,这会创建一个强引用,有时会引起问题。因此,[weak self]创建一个会悄悄消失的弱引用。 - Callam
1
另外,将[weak self]替换为[weak collectionView],然后您就可以在闭包中使用collectionView?.reloadData() - Callam
工作得很完美 - 这个链接也非常有用。非常感谢! - Ben

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接