我正在使用Kingfisher库来缓存UICollectionView单元格中的图像。
我注意到调用kf_setImage
(假设名为listCell
的单元名称及其ImageView名为imgMain
)如下:
listCell.imgMain.kf.setImage(with: URL(string: "MY IMAGE URL"),
placeholder: UIImage(named: "PLACEHOLDER IMAGE"))
工作正常,它会缓存图像并在单元格重新出列时显示它(当向上和向下滚动时,我可以直接看到图像而无需重新下载),但时我拉动刷新集合视图(调用具有相同确切参数的API,这意味着它将返回相同的图像URL)图像已被重新下载!我假设图像已经被缓存了。
为了更清楚,this link包含描述我所面对的gif图像。
那么,为什么图像会再次被下载?它是Kingfisher中缓存的默认行为吗?是否有任何配置应该按照我的预期进行编辑?
我读了library documentation,但是 - 很遗憾 - 我找不到与我所要求的相关的有用信息。
答案 0 :(得分:9)
Kingfisher默认使用整个URL作为缓存键,因此每次请求API时都必须确保图像具有非常的SAME url字符串。如果网址附加了时间戳或版本号,则缓存将失败。 (例如。http://example.com/image.png?time=123
和http://example.com/image.png?time=456
将被识别为两个不同的缓存键,尽管您可以从中获取相同的图像。)
这是我可以为您的操作绘制的唯一案例。如果这对您来说是正确的,您可以创建一个ImageResource
来明确指定缓存键(应该与您的原始URL相关,但要删除附加的内容):
let r = ImageResource(downloadURL: yourUrl, cacheKey: key)
imageView.kf.setImage(with: r, placeholder: yourImage)
答案 1 :(得分:1)
根据我之前看到的Kingfisher的行为,最初加载单元格是获取图像并保存到缓存中。
每当你滚动它时,它会处理图像的变化,重新加载,从缓存中获取等等。在你的Pull中刷新你重新加载你的数据源,所以Kingfisher会再次尝试重新加载缓存,当然,您可以避免使用Kingfisher手动处理缓存或在kf_setImage
方法的选项中指定。
如果看到方法kf_setImage
的签名:
public func kf_setImage(with resource: Resource?,
placeholder: Image? = nil,
options: KingfisherOptionsInfo? = nil,
progressBlock: DownloadProgressBlock? = nil,
completionHandler: CompletionHandler? = nil) -> RetrieveImageTask
默认情况下,options
参数nil
。您可以在这些参数中指定onlyFromCache
,如果设置,Kingfisher将只尝试从缓存中检索图像,而不是从网络中检索。
imageView.kf.setImage(with: url, options: [.onlyFromCache])
另一种方法是根据您的要求自定义ImageCache
和ImageDownloader
。
但是你需要小心,因为当你做一个Pull to Refresh时,默认行为应首先显示来自缓存的图像,并在它来自网络时更新它,所以你需要以某种方式处理它
我希望这可以帮到你