iOS

SDWebImage 5.0 (一、变化)

2018-11-08  本文已影响0人  纸飞机zhou

SDWebImage 5.x 相比 4.x 最大的变化之一是协议化了很多重要的对象,配合新引入的 SDWebImageContext/SDWebImageMutableContext 参数,保留快速使用特性的同时可以灵活的自定义高级功能。


1、主要协议化了的对象:

4.4 5.0
SDWebImageCacheSerializerBlock id<SDWebImageCacheSerializer>
SDWebImageCacheKeyFilterBlock id<SDWebImageCacheKeyFilter>
SDWebImageDownloader id<SDImageLoader>
SDImageCache id<SDImageCache>
SDWebImageDownloaderProgressBlock id<SDWebImageIndicator>

2、SDWebImageContext / SDWebImageMutableContext:

可以看到SDWebImageContext / SDWebImageMutableContext 其实就是
SDWebImageContextOption为key、id(指定类型或者协议)为value 的NSDictionary/NSMutableDictionary

typedef NSDictionary<SDWebImageContextOption, id> SDWebImageContext;
typedef NSMutableDictionary<SDWebImageContextOption, id>SDWebImageMutableContext;

而 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<SDImageTransformer> SDWebImageDefine.m
SDWebImageContextImageScaleFactor CGFloat SDWebImageDefine.m
SDWebImageContextStoreCacheType SDImageCacheType SDWebImageDefine.m
SDWebImageContextDownloadRequestModifier id<SDWebImageDownloaderRequestModifier> SDWebImageDefine.m
SDWebImageContextCacheKeyFilter id<SDWebImageCacheKeyFilter> SDWebImageDefine.m
SDWebImageContextCacheSerializer id<SDWebImageCacheSerializer> SDWebImageDefine.m
SDWebImageContextLoaderCachedImage UIImage/NSImage<SDAnimatedImage> SDImageLoader.m

来看下这些配置的作用:

2.1 SDWebImageContextSetImageOperationKey:

SDWebImageContextSetImageOperationKey是为UIView的相关子类及扩展服务的,SDWebImage在 UIView+WebCacheOperation 中为UIView添加了一个NSMapTable关联对象,用于保存多个图片加载线程:

typedef NSMapTable<NSString *, id<SDWebImageOperation>> SDOperationsDictionary;
  1. 简单来说,这个key对应的value用于指定当前的id<SDWebImageOperation>保存在NSMapTable中的key,后续的cancel、remove都需要通过这个key来找到对应的线程。

  2. 当指定同一个key加载图片时会先cancel之前存在的线程。

  3. SDWebImageContextSetImageOperationKey不是在所有地方使用都生效的。

比如UIButtonsd_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<SDImageTransformer>类型用于转换处理加载出来的图片。
SDWebImage内建了1个序列转换类以及8个常用的转换类:

类型 作用
SDImagePipelineTransformer 可以传入一个NSArray<id<SDImageTransformer>>按顺序做转换
SDImageRoundCornerTransformer 添加圆角
SDImageResizingTransformer 调整
SDImageCroppingTransformer 裁剪
SDImageFlippingTransformer 翻转
SDImageRotationTransformer 旋转
SDImageTintTransformer 添加色彩
SDImageBlurTransformer 添加模糊
SDImageFilterTransformer 添加滤镜
  1. SDWebImageManager中也可以设置一个id<SDImageTransformer>默认为nil,但是只有SDWebImageContext没有配置SDWebImageContextImageTransformer,才会使用它。
    也就是配置优先级 SDWebImageContext>SDWebImageManager
  2. 如果设置了id<SDImageTransformer>不会缓存原始图片,只缓存处理后的图片。
  3. 对于同个图片、不同参数的id<SDImageTransformer>会被认为是不同的图片:会产生不同的缓存文件、会重复下载。
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<SDWebImageDownloaderRequestModifier>,用于在加载图片前修改NSURLRequest

  1. SDWebImageContextDownloadRequestModifier协议比较简单,只需要实现一个方法,返回一个修改后的NSURLRequest即可:
- (nullable NSURLRequest *)modifiedRequestWithRequest:(nonnull NSURLRequest *)request;
  1. 内建了一个SDWebImageDownloaderRequestModifier对象,可以使用Block方便的修改NSURLRequest
2.7 SDWebImageContextCacheKeyFilter:

可以传入一个id<SDWebImageCacheKeyFilter>,指定图片的缓存key。

  1. SDWebImageCacheKeyFilter协议也比较简单,只需要实现一个方法,返回一个对应的缓存key字符串即可
- (nullable NSString *)cacheKeyForURL:(nonnull NSURL *)url;
  1. 内建了一个SDWebImageCacheKeyFilter对象,可以使用Block方便的返回缓存key
2.8 SDWebImageContextCacheSerializer:
  1. 可以传入一个id<SDWebImageCacheSerializer>,转换需要缓存的图片格式。
  2. SDWebImageManager中也可以设置一个id<SDWebImageCacheSerializer>默认为nil,但是只有SDWebImageContext没有配置SDWebImageContextCacheSerializer,才会使用它。
    也就是配置优先级 SDWebImageContext>SDWebImageManager
  3. 通常用于需要缓存的图片格式与下载的图片格式不相符的时候,如:下载的时候为了节约流量、减少下载时间使用了WebP格式,但是如果缓存也用WebP,每次从缓存中取图片都需要经过一次解压缩,这样是比较影响性能的,就可以使用id<SDWebImageCacheSerializer>,实现其中的协议方法:
- (nullable NSData *)cacheDataWithImage:(nonnull UIImage *)image originalData:(nullable NSData *)data imageURL:(nullable NSURL *)imageURL;

返回一个转成JPEG/PNG等格式的数据用于缓存。

2.9 SDWebImageContextLoaderCachedImage:

可以传入一个UIImage的缓存图像。

  1. 这个值比较特殊,它是定义在SDImageLoader.m中的。
  2. 这个值可以认为是SDWebImage是内部用来从SDWebImageManagerSDWebImageDownloader(id<SDImageLoader>)传递缓存图像的,自定义实现SDImageLoader协议可能会用到这个值,其他情况一般不会用到。
  3. 这个属性只有在 SDWebImageOptions包含SDWebImageRefreshCached策略时才生效,也就是他是SDWebImageRefreshCached这个策略的配套值。
  4. SDWebImageRefreshCached这个策略用于那些图片URL是静态的(图片更新时URL是不变的,SD给的例子是 Facebook graph api profile pics),这个时候它会根据HTTP header的 cache-control 字段来控制缓存并且使用NSURLCache来缓存图片,SDWebImageDownloader(id<SDImageLoader>)中判断SDWebImageContextLoaderCachedImage存在并且策略是SDWebImageRefreshCached的情况,仍然会发起请求。

3、通过图片看下SDWebImageContext有多重要:

1541668044415.jpg

从上图可以看到,SDWebImageContext就像一条「流水线」,把里面的参数项从最外层的View层一直传递到SDImageCacheSDWebImageDownloaderOperation。「流水线」经过的各个模块会从上去各自取自己感兴趣的东西使用(彩色实心箭头)

上一篇下一篇

猜你喜欢

热点阅读