SDWebImage 是一个基于 Objective-C 开发的强大的图片加载和缓存库。以下是对它的分析:
功能特点
- 异步加载:能在后台线程中下载图片,防止主线程阻塞,确保界面流畅性,例如在滚动 UITableView 或 UICollectionView 时,不会因图片加载而卡顿。
- 内存和磁盘双缓存:采用 NSCache 管理内存缓存,将压缩过的图片保存到磁盘缓存。内存缓存可快速响应图片请求,减少二次加载;磁盘缓存则在应用重启后仍能使用缓存图片,提升加载速度,节省流量2。
- 支持多种图片格式:支持 JPEG、PNG、GIF、WebP 等多种图片格式,满足不同场景需求,如展示动画表情或广告中的 GIF 图片,以及 WebP 格式图片以减少图片数据量,加快页面加载速度1。
- 保证图片下载唯一性:能确保相同 URL 的图片不会被多次下载,避免重复请求浪费资源,通过操作队列管理下载任务,对相同 URL 的请求进行合并或复用。
核心组件
- SDImageCache:主要处理缓存逻辑,包括 NSCache(Memory)、Disk 读写、清理 Old File 等。通过 NSOperation 管理 queue 任务,方便进行取消操作;还会申请系统后台时间处理任务,以在后台完成缓存清理等耗时操作。
- SDWebImageManager:作为外层管理 cache 和 download 的入口,调度 SDImageCache 和 SDWebImageDownloader 进行缓存和下载操作。在初始化时会创建 SDImageCache 和 SDWebImageDownloader 的实例,并使用信号量实现锁操作,保证线程安全。
- SDWebImageDownloader:提供了图片下载的功能,包括下载选项、下载顺序、下载管理器等。下载操作基于 NSURLConnection,将图片下载任务放在 NSOperationQueue 中执行,支持自定义下载逻辑和进度、完成等回调。
- SDWebImageCodersManager:整体 Coders 的入口,提供是否可 Coder 和 Coder 转发功能,用于图片的解码和编码操作,支持多种图片格式的解码,包括 GIF、WebP 等动态图的解码。
工作流程2
- 调用
setImageWithURL:placeholderImage:options:
方法,先显示占位图,然后 SDWebImageManager 根据 URL 开始处理图片。 - SDWebImageManager 调用
downloadWithURL:delegate:options:userInfo:
方法,交给 SDImageCache 从缓存查找图片。 - 先从内存图片缓存查找,若有则通过 SDImageCacheDelegate 回调到 SDWebImageManager,再由 SDWebImageManagerDelegate 回调到前端展示图片。
- 若内存缓存中没有,生成 NSInvocationOperation 添加到队列开始从硬盘查找。
- 根据 URLKey 在硬盘缓存目录下尝试读取图片文件,在 NSOperation 中操作,回主线程进行结果回调。
- 若从硬盘读取到图片,将其添加到内存缓存,然后回调展示图片。
- 若从硬盘缓存目录读取不到图片,说明所有缓存都不存在该图片,需要下载图片,回调给 SDWebImageManager。
- 共享或重新生成一个下载器 SDWebImageDownloader 开始下载图片。
- 图片下载由 NSURLConnection 来做,实现相关 delegate 判断图片下载状态。
- 数据下载完成后交给 SDWebImageDecoder 做图片解码处理,在 NSOperationQueue 完成,避免拖慢主线程。
- 在主线程宣告解码完成,回调给 SDWebImageDownloader,再回调给 SDWebImageManager 告知图片下载完成。
- 通知所有的 downloadDelegates 下载完成,回调给需要的地方展示图片。
- 将图片保存到 SDImageCache 中,内存缓存和硬盘缓存同时保存,写文件到硬盘在单独 NSInvocationOperation 完成,避免拖慢主线程。
优势与不足
- 优势:高效性能、多功能支持、易于集成,拥有强大的社区支持,有丰富的文档、示例代码和社区资源,能帮助开发者快速实现图片加载和缓存功能,适用于各种需要加载网络图片的 iOS 应用。
- 不足:在处理非常大的图片或大量图片同时加载时,可能会出现内存占用过高的问题,需要开发者合理配置缓存策略和进行内存管理。另外,对于一些特殊格式的图片或者最新的图片格式,可能需要额外的插件或扩展才能支持。
架构图
SDWebImage 架构
├── 视图扩展 (Categories)
│ ├── UIImageView+WebCache
│ ├── UIButton+WebCache
│ └── MKAnnotationView+WebCache
│ └── 方法:sd_setImageWithURL()
├── 核心管理层
│ └── SDWebImageManager (单例)
│ ├── 管理缓存 → SDImageCache
│ ├── 管理下载 → SDWebImageDownloader
│ └── 上下文 → SDWebImageContext
├── 缓存层
│ └── SDImageCache (单例)
│ ├── 内存缓存 → NSCache
│ ├── 磁盘缓存 → 基于 URL MD5 的文件存储
│ ├── 图片编解码 → SDImageCoder
│ └── 图片转换 → SDImageTransformer
├── 下载层
│ └── SDWebImageDownloader (单例)
│ ├── 下载任务 → SDWebImageDownloaderOperation
│ ├── 使用 NSURLSession
│ └── 支持 HTTP 认证、进度跟踪
└── 基础组件
├── 工具类 (Utils)
├── 图片编解码器 (SDImageCoder)
├── 图片转换器 (SDImageTransformer)
└── 兼容性适配 (SDWebImageCompat)