为什么已设置永不过期,Kingfisher 缓存的图片仍被清理?
问题产生原因
- 核心原因是 Kingfisher 默认磁盘缓存存储在系统的
Caches目录下:iOS 系统规则中,<Application_Home>/Library/Caches目录属于可清理目录,当设备存储空间不足时,系统会自动清理所有应用 Caches 目录下的未锁定文件,这个行为不受应用本身的缓存过期配置控制,你遇到的情况就是 Instagram 占用大量存储空间后,系统触发了存储清理,把你应用 Caches 目录下的 Kingfisher 缓存文件直接删除了。 - 你配置的
diskCacheExpiration(.never)和diskCacheAccessExtending(.expirationTime(.never))仅作用于 Kingfisher 自身的缓存淘汰逻辑,优先级远低于系统级的文件清理规则,无法阻止系统删除 Caches 目录下的文件。 - 额外排查点:如果你的应用累计缓存的图片大小已经达到 Kingfisher 默认的磁盘缓存上限(默认 500MB),Kingfisher 自身的 LRU 最近最少使用淘汰策略也会自动删除最久未使用的缓存文件,哪怕你设置了永不过期。
解决方案
如果需要缓存文件不会被系统自动清理,需要修改 Kingfisher 全局磁盘缓存的存储路径,改为存储到 Application Support 目录下,该目录系统不会自动清理,仅在用户卸载应用、手动清除应用全部数据时才会被删除。
全局配置代码示例:
// 在 App 启动时执行,比如 AppDelegate 的 didFinishLaunchingWithOptions 方法,或者 SwiftUI App 的 init 方法中 let cacheDir = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0] .appendingPathComponent("CustomImageCache", isDirectory: true) let diskConfig = DiskStorage.Config( name: "default", sizeLimit: 1024 * 1024 * 1024, // 自定义磁盘缓存上限,示例为 1GB directory: cacheDir, expiration: .never // 全局配置磁盘缓存永不过期 ) let memoryConfig = MemoryStorage.Config(totalCostLimit: 1024 * 1024 * 100) // 自定义内存缓存上限,示例为 100MB // 初始化自定义缓存并设为全局默认 let customCache = try! ImageCache(diskConfig: diskConfig, memoryConfig: memoryConfig) KingfisherManager.shared.defaultOptions = [.targetCache(customCache)]
如果不需要修改全局配置,也可以针对单个 KFImage 请求通过 .targetCache() 修饰符指定自定义的缓存对象。
内容的提问来源于stack exchange,提问作者Ufuk Köşker
相关产品推荐
相关产品推荐

