SDWebImage 5.x 相比 4.x 最大的變化之一是協(xié)議化了很多重要的對(duì)象缓艳,配合新引入的 SDWebImageContext/SDWebImageMutableContext
參數(shù)槽奕,保留快速使用特性的同時(shí)可以靈活的自定義高級(jí)功能嘴纺。
1败晴、主要協(xié)議化了的對(duì)象:
4.4 | 5.0 |
---|---|
SDWebImageCacheSerializerBlock | id<SDWebImageCacheSerializer> |
SDWebImageCacheKeyFilterBlock | id<SDWebImageCacheKeyFilter> |
SDWebImageDownloader | id<SDImageLoader> |
SDImageCache | id<SDImageCache> |
SDWebImageDownloaderProgressBlock | id<SDWebImageIndicator> |
2、SDWebImageContext / SDWebImageMutableContext:
可以看到SDWebImageContext / SDWebImageMutableContext
其實(shí)就是
以 SDWebImageContextOption
為key栽渴、id(指定類型或者協(xié)議)
為value 的NSDictionary/NSMutableDictionary
typedef NSDictionary<SDWebImageContextOption, id> SDWebImageContext;
typedef NSMutableDictionary<SDWebImageContextOption, id>SDWebImageMutableContext;
而 SDWebImageContextOption 是一個(gè)可擴(kuò)展的String枚舉
typedef NSString * SDWebImageContextOption NS_EXTENSIBLE_STRING_ENUM;
SDWebImage定義了10個(gè)SDWebImageContextOption
的key位衩、對(duì)應(yīng)的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 |
來(lái)看下這些配置的作用:
2.1 SDWebImageContextSetImageOperationKey:
SDWebImageContextSetImageOperationKey
是為UIView
的相關(guān)子類及擴(kuò)展服務(wù)的,SDWebImage在 UIView+WebCacheOperation 中為UIView
添加了一個(gè)NSMapTable
關(guān)聯(lián)對(duì)象熔萧,用于保存多個(gè)圖片加載線程:
typedef NSMapTable<NSString *, id<SDWebImageOperation>> SDOperationsDictionary;
簡(jiǎn)單來(lái)說(shuō)糖驴,這個(gè)key對(duì)應(yīng)的value用于指定當(dāng)前的
id<SDWebImageOperation>
保存在NSMapTable
中的key,后續(xù)的cancel佛致、remove都需要通過(guò)這個(gè)key來(lái)找到對(duì)應(yīng)的線程贮缕。當(dāng)指定同一個(gè)key加載圖片時(shí)會(huì)先cancel之前存在的線程。
SDWebImageContextSetImageOperationKey
并不是在所有地方使用都生效的俺榆。
比如UIButton
的sd_setImageWithURL:
和sd_setBackgroundImageWithURL:
系列方法感昼。
在其內(nèi)部需要通過(guò)這個(gè)這值來(lái)保存、區(qū)分不同狀態(tài)(UIControlState
)的圖片加載線程罐脊,所以即使設(shè)置了SDWebImageContextSetImageOperationKey
也會(huì)被覆蓋:
類型 | 默認(rèn)值 | 自定義設(shè)置是否有效 |
---|---|---|
UIImageView+WebCache |
{ViewClassName} |
是 |
UIView+WebCache |
{ViewClassName} |
是 |
NSButton+WebCache |
@"NSButtonAlternateImageOperation" |
否 |
UIButton+WebCache |
@"UIButtonBackgroundImageOperation{state}" @"UIButtonImageOperation{state}" |
否 |
UIImageView+HighlightedWebCache |
@"UIImageViewImageOperationHighlighted" |
否 |
2.2 SDWebImageContextCustomManager:
可以傳入一個(gè)自定義的SDWebImageManager
定嗓,默認(rèn)使用[SDWebImageManager sharedManager]
2.3 SDWebImageContextImageTransformer:
可以傳入一個(gè)id<SDImageTransformer>
類型用于轉(zhuǎn)換處理加載出來(lái)的圖片。
SDWebImage內(nèi)建了1個(gè)序列轉(zhuǎn)換類以及8個(gè)常用的轉(zhuǎn)換類:
類型 | 作用 |
---|---|
SDImagePipelineTransformer |
可以傳入一個(gè)NSArray<id<SDImageTransformer>> 按順序做轉(zhuǎn)換 |
SDImageRoundCornerTransformer |
添加圓角 |
SDImageResizingTransformer |
調(diào)整 |
SDImageCroppingTransformer |
裁剪 |
SDImageFlippingTransformer |
翻轉(zhuǎn) |
SDImageRotationTransformer |
旋轉(zhuǎn) |
SDImageTintTransformer |
添加色彩 |
SDImageBlurTransformer |
添加模糊 |
SDImageFilterTransformer |
添加濾鏡 |
- 在
SDWebImageManager
中也可以設(shè)置一個(gè)id<SDImageTransformer>
默認(rèn)為nil萍桌,但是只有SDWebImageContext
沒(méi)有配置SDWebImageContextImageTransformer
宵溅,才會(huì)使用它。
也就是配置優(yōu)先級(jí)SDWebImageContext
>SDWebImageManager
- 如果設(shè)置了
id<SDImageTransformer>
不會(huì)緩存原始圖片上炎,只緩存處理后的圖片恃逻。 - 對(duì)于同個(gè)圖片、不同參數(shù)的
id<SDImageTransformer>
會(huì)被認(rèn)為是不同的圖片:會(huì)產(chǎn)生不同的緩存文件藕施、會(huì)重復(fù)下載寇损。
2.4 SDWebImageContextImageScaleFactor:
在NSData
-> UIImage
時(shí)對(duì)圖片放大比例,是個(gè)大于1的CGFloat
值裳食,默認(rèn)值:
類型 | 值 |
---|---|
iOS and tvOS | [UIScreen mainScreen].scale |
watchOS | [WKInterfaceDevice currentDevice].screenScale |
macOS | [NSScreen mainScreen].backingScaleFactor |
2.5 SDWebImageContextStoreCacheType:
定義圖片緩存規(guī)則具體看 SDImageCacheType
中的定義矛市。
2.6 SDWebImageContextDownloadRequestModifier:
可以傳入一個(gè)id<SDWebImageDownloaderRequestModifier>
,用于在加載圖片前修改NSURLRequest
诲祸。
-
SDWebImageContextDownloadRequestModifier
協(xié)議比較簡(jiǎn)單浊吏,只需要實(shí)現(xiàn)一個(gè)方法憨愉,返回一個(gè)修改后的NSURLRequest
即可:
- (nullable NSURLRequest *)modifiedRequestWithRequest:(nonnull NSURLRequest *)request;
- 內(nèi)建了一個(gè)
SDWebImageDownloaderRequestModifier
對(duì)象,可以使用Block方便的修改NSURLRequest
2.7 SDWebImageContextCacheKeyFilter:
可以傳入一個(gè)id<SDWebImageCacheKeyFilter>
卿捎,指定圖片的緩存key配紫。
-
SDWebImageCacheKeyFilter
協(xié)議也比較簡(jiǎn)單,只需要實(shí)現(xiàn)一個(gè)方法午阵,返回一個(gè)對(duì)應(yīng)的緩存key字符串即可
- (nullable NSString *)cacheKeyForURL:(nonnull NSURL *)url;
- 內(nèi)建了一個(gè)
SDWebImageCacheKeyFilter
對(duì)象躺孝,可以使用Block方便的返回緩存key
2.8 SDWebImageContextCacheSerializer:
- 可以傳入一個(gè)
id<SDWebImageCacheSerializer>
,轉(zhuǎn)換需要緩存的圖片格式底桂。 - 在
SDWebImageManager
中也可以設(shè)置一個(gè)id<SDWebImageCacheSerializer>
默認(rèn)為nil
植袍,但是只有SDWebImageContext
沒(méi)有配置SDWebImageContextCacheSerializer
,才會(huì)使用它籽懦。
也就是配置優(yōu)先級(jí)SDWebImageContext
>SDWebImageManager
- 通常用于需要緩存的圖片格式與下載的圖片格式不相符的時(shí)候于个,如:下載的時(shí)候?yàn)榱斯?jié)約流量、減少下載時(shí)間使用了WebP格式暮顺,但是如果緩存也用WebP厅篓,每次從緩存中取圖片都需要經(jīng)過(guò)一次解壓縮,這樣是比較影響性能的捶码,就可以使用
id<SDWebImageCacheSerializer>
羽氮,實(shí)現(xiàn)其中的協(xié)議方法:
- (nullable NSData *)cacheDataWithImage:(nonnull UIImage *)image originalData:(nullable NSData *)data imageURL:(nullable NSURL *)imageURL;
返回一個(gè)轉(zhuǎn)成JPEG/PNG等格式的數(shù)據(jù)用于緩存。
2.9 SDWebImageContextLoaderCachedImage:
可以傳入一個(gè)UIImage
的緩存圖像惫恼。
- 這個(gè)值比較特殊档押,它是定義在
SDImageLoader.m
中的。 - 這個(gè)值可以認(rèn)為是SDWebImage是內(nèi)部用來(lái)從
SDWebImageManager
向SDWebImageDownloader
(id<SDImageLoader>
)傳遞緩存圖像的祈纯,自定義實(shí)現(xiàn)SDImageLoader
協(xié)議可能會(huì)用到這個(gè)值令宿,其他情況一般不會(huì)用到。 - 這個(gè)屬性只有在
SDWebImageOptions
包含SDWebImageRefreshCached
策略時(shí)才生效腕窥,也就是他是SDWebImageRefreshCached
這個(gè)策略的配套值粒没。 -
SDWebImageRefreshCached
這個(gè)策略用于那些圖片URL是靜態(tài)的(圖片更新時(shí)URL是不變的,SD給的例子是 Facebook graph api profile pics)油昂,這個(gè)時(shí)候它會(huì)根據(jù)HTTP header的 cache-control 字段來(lái)控制緩存并且使用NSURLCache
來(lái)緩存圖片革娄,SDWebImageDownloader
(id<SDImageLoader>
)中判斷SDWebImageContextLoaderCachedImage
存在并且策略是SDWebImageRefreshCached
的情況,仍然會(huì)發(fā)起請(qǐng)求冕碟。
3、通過(guò)圖片看下SDWebImageContext有多重要:
從上圖可以看到匆浙,SDWebImageContext
就像一條「流水線」安寺,把里面的參數(shù)項(xiàng)從最外層的View層一直傳遞到SDImageCache
和SDWebImageDownloaderOperation
∈啄幔「流水線」經(jīng)過(guò)的各個(gè)模塊會(huì)從上去各自取自己感興趣的東西使用(彩色實(shí)心箭頭)