尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Kingfisher 磁盘缓存异步写入未完成时如何用 waitForCache 选项等待

Kingfisher 磁盘缓存异步写入未完成时如何用 waitForCache 选项等待 Kingfisher 磁盘缓存异步写入未完成时如何用 waitForCache 选项等待【免费下载链接】KingfisherA lightweight, pure-Swift library for downloading and caching images from the web.项目地址: https://gitcode.com/GitHub_Trending/ki/Kingfisher在使用 Kingfisher 的视图扩展方法如imageView.kf.setImage(with:)加载图片时如果你想在 completion handler 里确认图片已经落盘到磁盘缓存会碰到一个时序问题磁盘缓存写入是异步的handler 触发时磁盘缓存可能还没更新完此时调用ImageCache.default.retrieveImageInDiskCache(forKey:)拿到的image可能是nil。本文的任务就是解决这个时序问题让你的业务逻辑安全地依赖磁盘缓存的存在性。问题根源磁盘缓存写入不阻塞 completion handlerKingfisher 的ImageCache采用内存 磁盘混合缓存。根据官方文档说明把图片存入磁盘缓存是异步操作视图扩展方法不需要等磁盘写入完成就去设置图片视图并调用 completion handler见 CommonTasks_Cache.md 中 Waiting for cache to finish 一节。也就是说下面这段代码中handler 执行时磁盘缓存“可能尚未写入”imageView.kf.setImage(with: url) { _ in ImageCache.default.retrieveImageInDiskCache(forKey: url.cacheKey) { result in switch result { case .success(let image): // image might be nil here. case .failure: break } } }文档同时说明大多数场景下这个异步行为不是问题只有当你的逻辑依赖磁盘缓存确实存在时才需要处理它。用 .waitForCache 选项等待缓存写盘完成解决方案是添加.waitForCache选项。加上它之后Kingfisher 会延迟执行 handler直到磁盘缓存操作完成imageView.kf.setImage(with: url, options: [.waitForCache]) { _ in ImageCache.default.retrieveImageInDiskCache(forKey: url.cacheKey) { result in switch result { case .success(let image): // image exists. case .failure: break } } }这是文档给出的标准改法只需要在options里加入.waitForCache其余加载代码不变。关于这个选项本身源码中的定义可以确认它的语义与默认值选项声明KingfisherOptionsInfo.swift 中case waitForCache的文档注释为 “When set, Kingfisher will wait for the caching operation to be completed before invoking the completion block.”对应的解析字段waitForCache默认值为false实现上KingfisherManager.swift 在缓存图片时通过CacheCallbackCoordinator(shouldWaitForCache: options.waitForCache, ...)决定是否等待磁盘缓存回调触发后再调用 completion。在 SwiftUI 侧用链式写法如果你用的是KFImage而不是 UIKit 的扩展方法KFOptionsSetter提供了对应的链式方法 waitForCache(::)参数enabled默认为true效果等价于把.waitForCache加入选项列表KFImage(url) .waitForCache() .onSuccess { _ in // 磁盘缓存写入已完成 }与 .cacheOriginalImage 组合时的行为如果你同时设置了.cacheOriginalImage在应用了自定义 processor 时把原图也缓存一份.waitForCache也会等待原图的缓存完成。这一点在 CHANGELOG.md 的 5.10.0 版本记录中有说明“The.waitForCacheoption now also waits for caching for original image if the.cacheOriginalImageis also set.”。因此在这种组合下handler 触发时图片缓存和原图缓存都已落盘。结果验证确认磁盘缓存确实存在在带.waitForCache的 completion handler 内部可以用文档中给出的两种检查方式验证磁盘缓存状态// 方式一直接取磁盘缓存中的图片 ImageCache.default.retrieveImageInDiskCache(forKey: url.cacheKey) { result in switch result { case .success(let image): print(image as Any) case .failure(let error): print(error) } } // 方式二只判断是否存在及缓存位置 let cache ImageCache.default let cached cache.isCached(forKey: url.cacheKey) // 是否存在 let cacheType cache.imageCachedType(forKey: url.cacheKey) // .memory / .disk / .none判断依据设置了.waitForCache后handler 执行时retrieveImageInDiskCache的.success分支应能拿到图片文档示例中标注为// image exists.imageCachedType(forKey:)返回.disk或.memory说明缓存可命中返回.none说明缓存中不存在。注意这些检查要用和图片相同的cacheKey如果加载时应用了 processor操作缓存时要带上processorIdentifier否则会查不到对应条目。边界与限制内存缓存无需等待。文档明确指出这一考虑只针对磁盘缓存因为磁盘缓存涉及异步 I/O内存缓存操作是同步的图片总是可用不存在同样的时序问题。选项默认关闭。KingfisherParsedOptionsInfo中waitForCache默认为false不显式开启就不会等待磁盘写入完成。适用版本。该选项自 4.9.02018-09-04起提供见 CHANGELOG.md 对应版本条目如果你在维护较老的代码库先确认 Kingfisher 版本不低于 4.9.0。磁盘清理操作是独立的。如果你需要主动清理磁盘缓存使用cache.clearDiskCache { ... }或cache.cleanExpiredDiskCache { ... }见 CommonTasks_Cache.md Clear the cache 一节这些异步操作通过自己的 completion 回调报告完成与.waitForCache无关。简言之只要你的 completion handler 逻辑要读磁盘缓存就在加载选项里加上.waitForCacheSwiftUI 场景用waitForCache()handler 触发时磁盘缓存写入已经完成可以直接据此做存在性判断。【免费下载链接】KingfisherA lightweight, pure-Swift library for downloading and caching images from the web.项目地址: https://gitcode.com/GitHub_Trending/ki/Kingfisher创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表