SDWebImage 5.x 相比 4.x 最大的变化之一是协议化了很多重要的对象,配合新引入的 SDWebImageContext/SDWebImageMutableContext
参数,保留快速使用特性的同时可以灵活的自定义高级功能。
1、主要协议化了的对象:
4.4 | 5.0 |
---|---|
SDWebImageCacheSerializerBlock | id |
SDWebImageCacheKeyFilterBlock | id |
SDWebImageDownloader | id |
SDImageCache | id |
SDWebImageDownloaderProgressBlock | id |
2、SDWebImageContext / SDWebImageMutableContext:
可以看到SDWebImageContext / SDWebImageMutableContext
其实就是
以 SDWebImageContextOption
为key、id(指定类型或者协议)
为value 的NSDictionary/NSMutableDictionary
typedef NSDictionary SDWebImageContext;
typedef NSMutableDictionarySDWebImageMutableContext;
而 SDWebImageContextOption 是一个可扩展的String枚举
typedef NSString * SDWebImageContextOption NS_EXTENSIBLE_STRING_ENUM;
SDWebImage定义了10个SDWebImageContextOption
的key、对应的value类型和定义的位置
Key | Value | Define |
---|---|---|
SDWebImageContextSetImageOperationKey |
NSString |
SDWebImageDefine.m |
SDWebImageContextCustomManager |
SDWebImageManager |
SDWebImageDefine.m |
SDWebImageContextImageTransformer |
id |
SDWebImageDefine.m |
SDWebImageContextImageScaleFactor |
CGFloat |
SDWebImageDefine.m |
SDWebImageContextStoreCacheType |
SDImageCacheType |
SDWebImageDefine.m |
SDWebImageContextDownloadRequestModifier |
id |
SDWebImageDefine.m |
SDWebImageContextCacheKeyFilter |
id |
SDWebImageDefine.m |
SDWebImageContextCacheSerializer |
id |
SDWebImageDefine.m |
SDWebImageContextLoaderCachedImage |
UIImage/NSImage |
SDImageLoader.m |
来看下这些配置的作用:
2.1 SDWebImageContextSetImageOperationKey:
SDWebImageContextSetImageOperationKey
是为UIView
的相关子类及扩展服务的,SDWebImage在 UIView+WebCacheOperation 中为UIView
添加了一个NSMapTable
关联对象,用于保存多个图片加载线程:
typedef NSMapTable> SDOperationsDictionary;
简单来说,这个key对应的value用于指定当前的
id
保存在NSMapTable
中的key,后续的cancel、remove都需要通过这个key来找到对应的线程。当指定同一个key加载图片时会先cancel之前存在的线程。
SDWebImageContextSetImageOperationKey
并不是在所有地方使用都生效的。
比如UIButton
的sd_setImageWithURL:
和sd_setBackgroundImageWithURL:
系列方法。
在其内部需要通过这个这值来保存、区分不同状态(UIControlState
)的图片加载线程,所以即使设置了SDWebImageContextSetImageOperationKey
也会被覆盖:
类型 | 默认值 | 自定义设置是否有效 |
---|---|---|
UIImageView+WebCache |
{ViewClassName} |
是 |
UIView+WebCache |
{ViewClassName} |
是 |
NSButton+WebCache |
@"NSButtonAlternateImageOperation" |
否 |
UIButton+WebCache |
@"UIButtonBackgroundImageOperation{state}" @"UIButtonImageOperation{state}" |
否 |
UIImageView+HighlightedWebCache |
@"UIImageViewImageOperationHighlighted" |
否 |
2.2 SDWebImageContextCustomManager:
可以传入一个自定义的SDWebImageManager
,默认使用[SDWebImageManager sharedManager]
2.3 SDWebImageContextImageTransformer:
可以传入一个id
类型用于转换处理加载出来的图片。
SDWebImage内建了1个序列转换类以及8个常用的转换类:
类型 | 作用 |
---|---|
SDImagePipelineTransformer |
可以传入一个NSArray 按顺序做转换 |
SDImageRoundCornerTransformer |
添加圆角 |
SDImageResizingTransformer |
调整 |
SDImageCroppingTransformer |
裁剪 |
SDImageFlippingTransformer |
翻转 |
SDImageRotationTransformer |
旋转 |
SDImageTintTransformer |
添加色彩 |
SDImageBlurTransformer |
添加模糊 |
SDImageFilterTransformer |
添加滤镜 |
- 在
SDWebImageManager
中也可以设置一个id
默认为nil,但是只有SDWebImageContext
没有配置SDWebImageContextImageTransformer
,才会使用它。
也就是配置优先级SDWebImageContext
>SDWebImageManager
- 如果设置了
id
不会缓存原始图片,只缓存处理后的图片。 - 对于同个图片、不同参数的
id
会被认为是不同的图片:会产生不同的缓存文件、会重复下载。
2.4 SDWebImageContextImageScaleFactor:
在NSData
-> UIImage
时对图片放大比例,是个大于1的CGFloat
值,默认值:
类型 | 值 |
---|---|
iOS and tvOS | [UIScreen mainScreen].scale |
watchOS | [WKInterfaceDevice currentDevice].screenScale |
macOS | [NSScreen mainScreen].backingScaleFactor |
2.5 SDWebImageContextStoreCacheType:
定义图片缓存规则具体看 SDImageCacheType
中的定义。
2.6 SDWebImageContextDownloadRequestModifier:
可以传入一个id
,用于在加载图片前修改NSURLRequest
。
-
SDWebImageContextDownloadRequestModifier
协议比较简单,只需要实现一个方法,返回一个修改后的NSURLRequest
即可:
- (nullable NSURLRequest *)modifiedRequestWithRequest:(nonnull NSURLRequest *)request;
- 内建了一个
SDWebImageDownloaderRequestModifier
对象,可以使用Block方便的修改NSURLRequest
2.7 SDWebImageContextCacheKeyFilter:
可以传入一个id
,指定图片的缓存key。
-
SDWebImageCacheKeyFilter
协议也比较简单,只需要实现一个方法,返回一个对应的缓存key字符串即可
- (nullable NSString *)cacheKeyForURL:(nonnull NSURL *)url;
- 内建了一个
SDWebImageCacheKeyFilter
对象,可以使用Block方便的返回缓存key
2.8 SDWebImageContextCacheSerializer:
- 可以传入一个
id
,转换需要缓存的图片格式。 - 在
SDWebImageManager
中也可以设置一个id
默认为nil
,但是只有SDWebImageContext
没有配置SDWebImageContextCacheSerializer
,才会使用它。
也就是配置优先级SDWebImageContext
>SDWebImageManager
- 通常用于需要缓存的图片格式与下载的图片格式不相符的时候,如:下载的时候为了节约流量、减少下载时间使用了WebP格式,但是如果缓存也用WebP,每次从缓存中取图片都需要经过一次解压缩,这样是比较影响性能的,就可以使用
id
,实现其中的协议方法:
- (nullable NSData *)cacheDataWithImage:(nonnull UIImage *)image originalData:(nullable NSData *)data imageURL:(nullable NSURL *)imageURL;
返回一个转成JPEG/PNG等格式的数据用于缓存。
2.9 SDWebImageContextLoaderCachedImage:
可以传入一个UIImage
的缓存图像。
- 这个值比较特殊,它是定义在
SDImageLoader.m
中的。 - 这个值可以认为是SDWebImage是内部用来从
SDWebImageManager
向SDWebImageDownloader
(id
)传递缓存图像的,自定义实现SDImageLoader
协议可能会用到这个值,其他情况一般不会用到。 - 这个属性只有在
SDWebImageOptions
包含SDWebImageRefreshCached
策略时才生效,也就是他是SDWebImageRefreshCached
这个策略的配套值。 -
SDWebImageRefreshCached
这个策略用于那些图片URL是静态的(图片更新时URL是不变的,SD给的例子是 Facebook graph api profile pics),这个时候它会根据HTTP header的 cache-control 字段来控制缓存并且使用NSURLCache
来缓存图片,SDWebImageDownloader
(id
)中判断SDWebImageContextLoaderCachedImage
存在并且策略是SDWebImageRefreshCached
的情况,仍然会发起请求。
3、通过图片看下SDWebImageContext有多重要:
从上图可以看到,SDWebImageContext
就像一条「流水线」,把里面的参数项从最外层的View层一直传递到SDImageCache
和SDWebImageDownloaderOperation
。「流水线」经过的各个模块会从上去各自取自己感兴趣的东西使用(彩色实心箭头)