序言
Kingfisher
是喵神的一个异步下载和缓存图片的Swift库,类似于OC 的SDWebImage
中文简介,github地址 我现在使用的3.版本不是很了解,直接以最新版本来学习了 由于个人水平有限 如有错误还望包涵
Kingfisher的架构
阅读他人优秀代码是一个提高自身代码水平很好的方法。花了几天的时间,看了Kingfisher
的源代码,里面包含的很多知识点,让我受益匪浅。3.x版本相比与之前的版本,一个重要的改变就是protocol
的灵活运用,更加面向协议编程。当然还有其他很多知识,比如多线程,枚举,闭包,Extension 等等应用。 Kingfisher中
有Core
,Extension
,Helpers
三个目录结构 共20个文件
Coreimage.swift
文件内部对 UIImage 以及 NSData 进行了拓展, 包含判定图片类型、图片解码以及Gif数据处理等操作Indicator.swift
图片加载时loading指示ImageCache.swift
主要负责将加载过的图片缓存至本地。ImageDownloader.swift
负责下载网络图片。ImagePrefetcher.swift
可用于提前指定一些图片下载ImageProcessor.swift
可用于将下载的数据合成图片对象CacheSerializer.swift
可用于图像对象序列化成图像数据存储到磁盘缓存和从磁盘缓存将图片数据反序列化成图像对象。RequestModifier.swift
下载图像请求修改器。ImageTransition.swift
过渡动画效果 使用UIViewAnimationOptions
动画效果KingfisherManager.swift
Kingfisher 管理控制类,拥有图片下载及缓存功能KingfisherOptionsInfo.swift
枚举KingfisherOptionsInfoItem 配置 Kingfisher 行为的参数,包括 是否自定义缓存对象 是否自定义下载器 是否过渡动画 是否设置下载低优先级 是否强制刷新 是否仅获取缓存图片 是否仅缓存至内存、是否允许图像后台解码等设置。Filter.swift
图像过滤器Resource.swift
记录了图片的下载地址和缓存Key。Kingfisher.swift
添加KingfisherCompatible通用协议 kf新属性
ExtensionImageView+Kingfisher.swift
UIButton+Kingfisher.swift
NSButton+Kingfisher
对 UIImageView
UIButton
NSButton
进行了拓展 主要用于提供 Kingfisher 的外部接口。
HelpersString+MD5.swift
负责图片缓存时对文件名进行MD5加密操作。Box.swift
一个简单泛型类ThreadHelper.swift
中的 dispatch_async_safely_main_queue
函数接受一个闭包 利用 NSThread.isMainThread 判断并将其放置在主线程中执行
Kingfisher.swift
主要文件ImageView+Kingfisher
,KingfisherManager
,ImageCache
,ImageDownloader
,废话不多说直接代码学习
运行demo 下面有这么一段代码:
首先调用的UIImageView
的kf
属性 之前是调用UIImageView
的Extension
中的kf_setImage
,现已弃用 那kf
属性是如何实现的?
下面是Kingfisher.swift
源码
- 自定义了不同平台下的一些类型别名 swift中的typealias 相当于OC中的typedef
|
|
- 申明了泛型类Kingfisher 实现了一个简单构造器,其中上面的cellImageView就是base属性
|
|
- 申明KingfisherCompatible协议 有一个可读属性kf 其类型是关联类型
|
|
- KingfisherCompatible协议的实现 属性kf关联Kingfisher类型 返回一个Kingfisher实例 base 参数就是传入的self
|
|
- Image ImageView Button 遵守 KingfisherCompatible 协议 所以上边的self参数就是遵守了协议的类型 因此base属性即cellImageView
|
|
ImageView+Kingfisher
现在来说说setImage
这个方法的实现 这个方法是在Kingfisher
的Extension 中实现 并且要求Base
属于UIImageView
类型 即where Base: ImageView
由于kf
属性关联了Kingfisher
所以可以调用(cell as! CollectionViewCell).cellImageView.kf.setImage
Extensions目录下的三个文件都是类似实现的 这里就以ImageView+Kingfisher.swift为例
下面方法是外部使用Kingfisher最频繁也是最重要的方法
第一个参数Resource
是一个URL遵守的Protocol,一般传入图片的URL,不可为空
第二个参数placeholder
是一个默认的占位图,可为空
第三个参数KingfisherOptionsInfo
是个枚举数组,配置Kingfisher下载图片的一些操作行为
第四个参数DownloadProgressBlock
是个下载进度闭包,可以用于更新下载UI
第五个参数completionHandler
是个下载完成闭包,闭包参数包含图片,错误,缓存类型,URL 信息
|
|
ImageView+Kingfisher
中的WebUR
,indicatorType
,indicator
, imageTask
属性均使用属性关联技术实现数据的存取
KingfisherManager
该类是Kingfisher
唯一的一个管理调度类。这个类有下载和缓存两大功能模块 主要包含了两个属性 两个方法
public var cache: ImageCache
图片缓存属性
public var downloader: ImageDownloader
图片下载属性
func downloadAndCacheImage
下载并且缓存图片方法func tryToRetrieveImageFromCache
获取缓存图片
在ImageView+Kingfisher
中最后图片的获取就是由KingfisherManager
的单例实现的retrieveImage
- 外部调用获取图片方法
|
|
- 下载并且缓存图片的方法
|
|
- 优先从缓存获取图片,如缓存中没有,在从网络获取图片
|
|
KingfisherOptionsInfo
上面代码多次用到options
这个参数,它的参数类型是KingfisherOptionsInfo
是一个类型别名public typealias KingfisherOptionsInfo = [KingfisherOptionsInfoItem]
KingfisherOptionsInfoItem
是一个枚举 配置 Kingfisher
所有功能行为 下面是详细中文注释
|
|
下面是自定义<== 运算符 比较两个KingfisherOptionsInfoItem 是否相等 相等返回true 否则返回false
|
|
下面是对CollectionType
的一个扩展 返回匹配的第一个相同枚举值 上面过渡动画就有用到
|
|
在KingfisherOptionsInfo
中有很多的类似的属性get方法 如下是关于图片编码的,默认返回DefaultCacheSerializer.default
。如果要自定义图片编码,可以添加自定义CacheSerializer
到Options
数组
|
|
结束
至此,我们对Kingfisher对整体架构已经有比较清晰的认识了 如下图所示
由于源代码比较多,一些注释都写在代码部分,可能看起来有点怪 用简书也有段时间,但这还是第一次自己写文章 接下来我会继续学习下载模块和缓存模块的过程等等 如有错误,希望大家不吝指正