5

我正在使用Kingfisher库来缓存 UICollectionView 单元格中的图像。

我注意到调用kf_setImage(假设调用的单元格的名称listCell及其 ImageView 调用imgMain)如下:

listCell.imgMain.kf.setImage(with: URL(string: "MY IMAGE URL"),
                             placeholder: UIImage(named: "PLACEHOLDER IMAGE"))

工作正常,它会缓存图像并在单元格重新出列时显示它(上下滚动时,我可以直接看到图像而无需重新下载它),但是当我拉动以刷新集合视图时(回想一下API具有相同的确切参数,这意味着它将返回相同的图像url)图像已重新下载!我假设图像已经被缓存。

为了更清楚,此链接包含描述我所面临的情况的 gif 图像。

那么,为什么图像会再次下载?这是 Kingfisher 中缓存的默认行为吗?是否有任何配置应该编辑以按我预期的方式运行?

我阅读了图书馆文档,但 - 不幸的是 - 我找不到与我所要求的相关的有用信息。

4

2 回答 2

11

Kingfisher 默认使用整个 url 作为缓存键,因此您必须确保每次请求 API 时都有相同的图像 url 字符串。如果 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)
于 2017-03-28T01:39:55.657 回答
1

根据我之前看到的 Kingfisher 的行为,单元格的加载最初是获取图像并保存到缓存中。

每次滚动它时都会处理图像的变化,重新加载,从缓存中获取等。在您的 Pull to refresh 中,您正在重新加载数据源,因此 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])

如果根据您的要求定制ImageCacheand的另一种方式。ImageDownloader

但是您需要小心,因为当您执行 Pull to Refresh 时,默认行为应该首先显示缓存中的图像并在它来自网络时对其进行更新,因此您需要以某种方式处理它。

我希望这对你有帮助

于 2017-03-27T15:04:53.890 回答