You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

图片缓存:如何控制磁盘缓存数量及持久化(Nuke/Kingfisher)

针对你遇到的图片缓存持久化和数量限制问题,我来给你梳理下可行的方案:

用Nuke实现持久化缓存并限制数量

你之前用Nuke时出现离开视图后缓存失效的情况,大概率是没有正确配置磁盘缓存的持久化策略。Nuke默认的磁盘缓存具备持久化能力,但需要手动配置数量限制来满足你“最多20张”的需求:

首先在App启动阶段(比如AppDelegatedidFinishLaunching方法里)自定义缓存配置:

do {
    // 创建磁盘缓存实例,设置最大缓存数量为20
    let diskCache = try DiskCache(
        name: "com.yourapp.custom.image.cache",
        sizeLimit: 0, // 不限制缓存总大小,只限制数量
        countLimit: 20
    )
    // 配置全局图片管道
    let pipelineConfig = ImagePipeline.Configuration()
    pipelineConfig.dataCache = diskCache
    // 可选:同时配置内存缓存的数量限制
    pipelineConfig.imageCache = ImageCache(countLimit: 20)
    
    ImagePipeline.shared = ImagePipeline(configuration: pipelineConfig)
} catch {
    print("初始化磁盘缓存失败:\(error)")
}

之后加载图片时,直接使用全局管道即可,缓存会自动持久化到磁盘,且数量超过20时自动清理最旧的缓存:

ImagePipeline.shared.loadImage(with: url, into: imageView)

优化你的Kingfisher实现(补充数量限制)

你已经用Kingfisher实现了基本的磁盘缓存逻辑,但还没设置数量限制。要达到最多20张的要求,只需要在全局配置里添加限制即可:

同样在App启动时配置:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    let defaultCache = ImageCache.default
    // 设置磁盘缓存最大数量为20
    defaultCache.diskStorage.config.countLimit = 20
    // 可选:设置内存缓存的数量限制
    defaultCache.memoryStorage.config.countLimit = 20
    
    return true
}

另外,你的加载代码可以简化,Kingfisher本身提供了更简洁的链式API,不需要手动拆分retrievedownload步骤:

func loadTargetImage(id: String, url: URL) {
    galleryImageView.kf.setImage(
        with: url,
        options: [.cacheOriginalImage]
    ) { result in
        switch result {
        case .success(let value):
            print("图片加载成功,来源:\(value.cacheType.rawValue)")
        case .failure(let error):
            print("图片加载失败:\(error.localizedDescription)")
        }
    }
}

这样Kingfisher会自动优先从磁盘缓存读取,其次是内存缓存,最后才发起网络请求,且会严格遵守你设置的20张数量限制,超过后自动淘汰最早的缓存文件。

关于直接存Documents目录的问题

你之前直接把图片存到Documents目录确实不是最优方案:一方面系统不会自动清理这个目录的文件,容易导致App占用空间过大;另一方面手动管理缓存的过期、数量限制、命中逻辑会非常繁琐。而Nuke或Kingfisher这类成熟的图片加载框架,已经封装了完善的缓存管理机制,能自动处理缓存清理、持久化、命中策略等问题,远比手动实现高效可靠。

内容的提问来源于stack exchange,提问作者RealNmae

火山引擎 最新活动