Kingfisher — 是什么、关键概念及 ImageCache

作者: IT Sectr 发布日期: 2026-05-05 阅读时间: 8 分钟

Kingfisher 是一个用于在 iOS、macOS 和 watchOS 上加载和缓存图像的库,使用纯 Swift 编写。根据 官方仓库,该库完全支持 Swift Concurrency、Combine 和 SwiftUI,以及自动两级缓存。Kingfisher 以其类型安全的 API 和与 Swift 项目的轻松集成而闻名。

要点

  • Kingfisher — 纯 Swift 图像加载库,支持 async/await、Combine 和 SwiftUI。
  • KingfisherManager — 统一的加载入口点,跟踪缓存和网络请求。
  • ImageCache 实现两级存储:内存缓存和磁盘缓存,可配置限制。
  • ImageProcessor — 用于转换的协议:调整大小、圆角、模糊、添加水印。
  • KFImage — SwiftUI 的视图组件,可声明性描述加载状态。

什么是 Kingfisher?

Kingfisher — 一个用于在 Apple 平台上异步加载和缓存图像的库,完全用 Swift 编写。该库的作者是 Wei Wang(onevcat)。Kingfisher 提供了一套工具,用于从网络加载图像,具有自动缓存、转换和对现代 Swift 技术(async/await、Combine、Sendable)的支持。

该库在 GitHub 上拥有超过 23,000 颗星,并用于 Telegram、Snapchat 和 Dropbox 等应用中。Kingfisher 支持 GIF、APNG、HEIF 和所有标准图像格式。每个请求都返回类型安全的 Result,消除了类型转换错误。

Kingfisher 的架构基于三个主要组件:Manager(加载管理器)、Cache(两级缓存)和 Processor(转换)。这些组件通过协议连接,允许在不更改依赖关系的情况下替换任何部分。

Kingfisher 如何工作:Manager 和 Cache

KingfisherManager — 协调图像加载、缓存和处理的中央类。它包含对 ImageCache 和 ImageDownloader 的引用,并提供统一的 retrieveImage 方法,在通过所有阶段后返回准备好的图像。

加载过程

在调用 retrieveImage 时,Manager 首先检查内存缓存 — 带有 UIImage 的 NSCache,其中的键由源 URL 和 CacheSerializer 构成。如果找到图像,立即返回。如果未找到,则检查磁盘缓存 — 从文件系统读取并通过 serializer 解密。如果磁盘缓存为空,则通过 ImageDownloader 执行网络请求,结果被解码、转换并保存到两个缓存级别。

  • 内存缓存 — 基于 NSCache,在内存警告时自动清除
  • 磁盘缓存 — 带 TTL 和大小限制检查的文件存储
  • ImageDownloader — 基于 URLSession,支持通过修改器修改请求

Swift Concurrency

从 7.0 版本开始,Kingfisher 完全支持 async/await。retrieveImage 方法可作为异步函数使用,无需完成块即可直接返回 Result。这允许在现代 Swift 架构中使用 Structured Concurrency 进行库操作。

Kingfisher 的主要模块

Kingfisher 分为多个模块,每个模块解决自己的任务。这种划分简化了组件的测试和替换。

KingfisherManager

KingfisherManager — 结合加载、缓存和处理器的外观。默认使用单例 KingfisherManager.shared,但可以为隔离场景(例如单元测试)创建具有自定义设置的单独实例。

ImageCache

ImageCache — 两级缓存,内存和磁盘具有单独的设置。内存缓存没有对象数量限制,但在内存不足时由系统清除。磁盘缓存将文件存储在目录中,具有 TTL 设置(默认 7 天)、大小限制(默认 0 — 无限制)和自动清除。

ImageProcessor

ImageProcessor — 具有单个方法 process(item:options:) 的协议,返回处理后的图像。内置实现:ResizingImageProcessor(调整大小)、RoundCornerImageProcessor(圆角)、BlurImageProcessor(高斯模糊)、OverlayImageProcessor(叠加颜色)。处理器可通过 |> 运算符组合。

Kingfisher 的缓存系统

Kingfisher 的缓存架构基于 write-through 原则:数据同时写入两个级别,读取从最快的级别 — 内存开始。缓存键是删除查询参数后的图像绝对 URL。

参数内存缓存磁盘缓存
存储NSCache(RAM)文件系统(SSD)
格式UIImage(已解码)Data(已压缩,通过 serializer)
清除UIApplication.didReceiveMemoryWarningNotificationTTL + 超出限制
序列化不需要CacheSerializer(默认 PNG/JPEG)
线程安全是(同步访问)是(IO 队列 + 屏障)

对于管理磁盘缓存大小,使用按最后访问日期排序计算文件总大小。当超出限制时,删除具有最早访问日期的文件,直到大小降至限制的 50% 以下。TTL 清除在缓存初始化和每次调用 cleanExpired 时发生。

在 Swift 中使用 Kingfisher 的示例

Kingfisher 提供了多个加载图像的接口:UIImageView 扩展、单独的管理器和 SwiftUI 视图。

通过 kf 在 UIImageView 中加载

kf — UIImageView 上的命名空间属性,提供 setImage、cancelDownload 方法和加载指示器。setImage 方法接受 URLSource 和可选的 Options 参数及 completionHandler。

swift
import Kingfisher

imageView.kf.setImage(
    with: URL(string: "https://example.com/image.jpg"),
    placeholder: UIImage(named: "placeholder"),
    options: [
        .processor(RoundCornerImageProcessor(radius: .point(12))),
        .transition(.fade(0.3)),
        .cacheMemoryOnly
    ],
    progressBlock: { receivedSize, totalSize in
        print("已加载 \(receivedSize) / \(totalSize)")
    }
)

该方法返回 DownloadTask,支持通过 cancel 取消和跟踪进度。在内部,setImage 调用 KingfisherManager.shared.retrieveImage,自动将 ImageView 确定为 Target。

使用 async/await

从 Kingfisher 7.0 开始,setImage 方法在异步版本中可用。这允许将图像加载集成到 Swift Structured Concurrency 中,无需回调。

swift
func loadAvatar() async {
    do {
        let result = try await imageView.kf.setImage(
            with: url,
            options: [.processor(ResizingImageProcessor(
                targetSize: CGSize(width: 100, height: 100)
            ))]
        )
        // result.image 包含 UIImage
    } catch {
        print("失败: \(error)")
    }
}

用于 SwiftUI 的 KFImage

KFImage — SwiftUI 视图,类似于 iOS 15 的 AsyncImage,但具有 Kingfisher 缓存的完整支持。该视图自动使用 KingfisherManager.shared,但通过 .configure 修改器支持自定义管理器。

swift
struct AvatarView: View {
    let url: URL

    var body: some View {
        KFImage(url)
            .placeholder { ProgressView() }
            .resizable()
            .fade(duration: 0.25)
            .forceTransition()
            .frame(width: 80, height: 80)
            .cornerRadius(40)
    }
}

Kingfisher 中的加载指示器

Kingfisher 提供内置指示器系统来显示图像加载进度。IndicatorType — 包含三个变体的枚举:.activity(UIActivityIndicatorView)、.progress(UIProgressView)和 .custom(Indicator 协议的自定义实现)。指示器在加载期间自动显示在 ImageView 上,完成后隐藏。

对于自定义指示器,需要实现 Indicator 协议,包含 startAnimatingView() 和 stopAnimatingView() 方法。这允许使用混合解决方案:带有 shimmer 动画的骨架、带有逐渐显示的占位图像或带有透明度动画的标志。Kingfisher 还支持通过 KingfisherManager.shared.defaultOptions 全局设置指示器。

Kingfisher 对比 SDWebImage

在 iOS 平台上,Kingfisher 和 SDWebImage 是两个主导的图像加载库。它们之间的选择取决于项目语言、性能要求和生态系统。

标准KingfisherSDWebImage
语言Swift(100%)Objective-C + Swift
Async/Await原生支持通过包装器
Combine内置发布者
Sendable支持有限
类型安全完全(Result 类型)通过 Any?
ImageProcessor通过 |> 组合通过 && 转换
大小~900 KB~1.2 MB
GitHub 星标23,000+25,000+

Kingfisher 的主要优势在于其 Swift-first 架构:完全支持 async/await、Combine Publishers、Sendable 和 Result 类型。SDWebImage 凭借更广泛的插件生态系统(WebP、SVG、MapKit)和对 Objective-C 的支持保持领先地位。

在 iOS 项目中配置 Kingfisher

Kingfisher 通过 Swift Package Manager、CocoaPods 或 Carthage 安装。安装后,只需导入模块并调用任何加载方法即可 — 该库无需额外配置即可使用。

swift
// Swift Package Manager (Package.swift)
dependencies: [
    .package(
        url: "https://github.com/onevcat/Kingfisher.git",
        from: "7.12.0"
    )
]

// CocoaPods (Podfile)
pod 'Kingfisher', '~> 7.12'

对于自定义全局设置,使用 KingfisherManager.shared。可以更改加载器超时、缓存策略和默认处理器。以下是 500 MB 缓存配置示例,TTL 为 14 天。

swift
let cache = ImageCache(name: "custom")
cache.memoryStorage.config.totalCostLimit = 100 * 1024 * 1024
cache.diskStorage.config.sizeLimit = 500 * 1024 * 1024
cache.diskStorage.config.expiration = .days(14)
KingfisherManager.shared.cache = cache

ImageDownloader 也通过管理器配置:可以设置具有超时、标头和缓存策略的自定义 URLSessionConfiguration。要监视进度,可使用 KFIndicator 模块,支持 ActivityIndicator、ProgressView 和自定义指示器。

常见问题

什么是 Kingfisher,它有什么用途?

Kingfisher — 用于 iOS 的图像加载库,使用纯 Swift 编写。它用于从网络异步加载、缓存和转换图像,完全集成到 SwiftUI、UIKit 和现代 Swift 技术中。

如何通过 Swift Package Manager 安装 Kingfisher?

在 Xcode 中通过 File → Add Packages 添加 https://github.com/onevcat/Kingfisher.git 包,版本从 7.12.0 开始。或者在 Package.swift 中指定依赖关系,参数 from: “7.12.0”。安装后,导入 Kingfisher 模块。

Kingfisher 支持哪些图像格式?

Kingfisher 支持 JPEG、PNG、GIF、APNG、HEIF 和 WebP。所有格式都通过系统框架(ImageIO、CoreGraphics)解码。GIF 通过 CGImageSource 支持,具有渐进加载和动画功能。

Kingfisher 相对于 SDWebImage 的优势是什么?

Kingfisher 使用纯 Swift 编写,完全支持 async/await、Combine 和 Sendable。它提供类型安全的 Result API 和通过协议的模块化架构,简化了组件替换和测试。

如何清除 Kingfisher 的缓存?

要清除内存缓存,调用 KingfisherManager.shared.cache.clearMemoryCache()。对于磁盘缓存,使用 clearDiskCache()。仅删除过期文件 — cleanExpiredDiskCache()。缓存大小通过 cache.calculateDiskStorageSize() 检查。

总结

  • Kingfisher — 纯 Swift 的现代图像加载库,支持所有当前的 Apple 技术。
  • 两级缓存(内存 + 磁盘)具有可配置限制和 TTL,确保快速访问和最小流量消耗。
  • Async/Await 和 Combine 允许将加载嵌入到任何架构中,无需回调和委托。
  • KFImage 为 SwiftUI 提供声明性 API,具有占位符、错误处理和自定义过渡效果。
  • ImageProcessor 通过 |> 运算符进行组合,在创建转换链时提供了灵活性。
  • 类型安全 Result 消除了处理结果时的运行时错误。
  • 模块化架构 通过协议允许替换 Manager、Cache 和 Downloader 以进行测试和自定义。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读