You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Kingfisher实现图片逐帧缓存并循环复用缓存资源的问题

解决方案

要实现首次加载图片后循环复用缓存、无需重复发起网络请求的需求,你可以通过调整Kingfisher的配置选项+优化预加载逻辑来实现:

1. 配置Kingfisher缓存策略

修改UIImageView扩展的setImage方法,添加缓存优先的核心配置,确保优先读取本地缓存,仅在缓存不存在时才发起网络请求:

extension UIImageView {
    func setImage(imageUrl: String, completion: (() -> ())? = nil) {
        guard let url = URL(string: imageUrl) else { 
            completion?()
            return 
        }
        let options: KingfisherOptionsInfo = [
            .alsoPrefetchToMemory,
            // 核心:优先用缓存,无缓存再请求网络
            .cachePolicy(.returnCacheDataElseLoad),
            // 确保图片缓存到磁盘,App重启后仍可复用
            .cacheOriginalImage
        ]
        self.kf.setImage(with: url, options: options) { _ in
            completion?()
        }
    }
}
  • .cachePolicy(.returnCacheDataElseLoad):强制Kingfisher先检查内存+磁盘缓存,存在则直接复用,不存在才发起网络请求。
  • .cacheOriginalImage:保证原始图片被持久化到磁盘缓存,避免App重启后需要重新加载。
  • .alsoPrefetchToMemory:保留该选项,将图片预加载到内存缓存,切换时读取速度更快。

2. 首次加载时批量预加载所有图片

为了让首次循环时所有图片都已缓存完成,避免切换过程中仍有网络请求,可在configureView中添加批量预加载逻辑:

func configureView(images: ApiImages) {
    guard let images = images.images else { return }
    imagesArray = images
    imagesCount = images.count
    
    // 批量预加载所有图片到缓存
    let imageURLs = images.compactMap { URL(string: $0) }
    ImagePrefetcher(urls: imageURLs).start()
    
    // 启动第一张图展示与动画
    imageView.setImage(imageUrl: images[nextImage])
    nextImage += 1
    animateImage()
}

使用ImagePrefetcher可以一次性将所有图片预加载到缓存,首次循环过程中后续图片已提前缓存完成,切换时直接读取缓存即可。

3. 优化动画冲突问题(可选)

你的UIView过渡动画时长是0.1秒,而原代码中Kingfisher自带0.5秒的过渡动画,两者会导致动画效果异常。建议移除Kingfisher的过渡动画,统一使用UIView的动画逻辑:

// 扩展中移除.transition(.fade(0.5))选项
extension UIImageView {
    func setImage(imageUrl: String, completion: (() -> ())? = nil) {
        guard let url = URL(string: imageUrl) else { 
            completion?()
            return 
        }
        let options: KingfisherOptionsInfo = [
            .alsoPrefetchToMemory,
            .cachePolicy(.returnCacheDataElseLoad),
            .cacheOriginalImage
        ]
        self.kf.setImage(with: url, options: options) { _ in
            completion?()
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 15:36:08