[iOS/OC]SDWebImage和LKImage對比

0x0背景

原本是放到自己博客的,不怎么用了,把文章同步過來,原文地址[iOS/OC]SDWebImage和LKImage對比

LKImageKit是騰訊開源的一個高性能圖片加載框架,雖然第一時間下載了源碼,但是只是簡單的看了框架,沒有細致的研讀源碼。最近空閑下來,學習了一下LKImageKit源碼,其中有很多巧妙的實現(xiàn)。本文將通過1張圖片的加載流程,對比兩個圖片框架。

0x1正文

LKImageKit和SDWebImage分別選用了兩種不同的圖片加載方案。LKImageKit的圖片加載是提供了一個LKImageView,加載圖片需要使用指定的容器。SDWebImage是寫了一個Category,加載圖片可以使用系統(tǒng)的UIImageView或其子類。流程上。

1.入口

發(fā)起一個圖片加載,LKImageKit是在layoutSubviews時,發(fā)起1次圖片加載,SDWebImage提供了1個主動發(fā)起圖片加載請求的接口sd_setImageWithUrl

LKImageKit發(fā)起圖片加載:

// 上層調(diào)用
imageView.URL = [NSURL urlWithString:@"https://xxx.png"];
imageView.request.synchronized = YES;

// 底層加載
- (void)layoutSubviews {
    [super layoutSubviews];
    [self layoutAndLoad];
}

SDWebImage發(fā)起圖片加載

// 上層調(diào)用
[imageView sd_setImageWithURL:[NSURL URLWithString:@""]];

// 之后開始下載流程

兩個圖片庫都提供了加載回調(diào),不同的是,LKImageKit提供的是delegate的方法,SDWebImage提供的是callback

LKImageKit

@protocol LKImageViewDelegate <NSObject>
@optional

- (void)LKImageViewImageLoading:(LKImageView *)imageView request:(LKImageRequest *)request;
- (void)LKImageViewImageDidLoad:(LKImageView *)imageView request:(LKImageRequest *)request;

@end

SDWebImage

typedef void(^SDWebImageCompletionBlock)(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL);

2.下載

LKImageKit進行圖片下載會統(tǒng)一由LKImageManger進行管理,LKImageKit提供的請求合并的優(yōu)化就是通過LKImageManager進行的。請求會通過blockOperation放到1個operationQueue中進行多個加載請求的隊列管理。

資源加載則由LKImageLoader進行,由單例LKImageLoaderManager進行管理。網(wǎng)絡下載是LKImageNetworkFileLoader進行,使用了NSURLSession,本地圖片加載通過LKImageLocalFileLoader進行。

[requestLV2.loader dataWithRequest:requestLV2
                          callback:^(LKImageRequest *requestLV2, NSData *data, float progress, NSError *error) {
                              [self loadDataRequestFinished:requestLV2 data:data progress:progress error:error];
                          }];

SDWebImage進行圖片下載由SDWebImageManager進行管理。類似的,在SDWebImage 5.0版本開始,也使用SDWebImageLoader進行加載,使用SDWebImageLoadersManager進行管理。網(wǎng)絡下載使用SDWebImageDownloader進行。使用NSOperation進行下載管理。

[self downloadImageWithURL:url options:downloaderOptions context:context progress:progressBlock completed:completedBlock];

對比可知,LKImageKit在下載前做了很多優(yōu)化,下載流程的管理更加細膩。SDWebImage的下載過程由于歷史原因,雖然在5.0上大刀闊斧的改造了很多東西,但是整體流程會顯得更加笨重一些。

3.圖片解碼

LKImageKit和SDWebImage的圖片解碼大同小異,以LKImageKit為例:

// 由LKImageDecoderManager進行解碼器的管理
UIImage *image = [decoder imageFromData:data request:request error:&decode_error];

// 普通靜圖
result = [UIImage imageWithData:data scale:[UIScreen mainScreen].scale];

// 1幀的動圖
UIImage *image = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:orientation];

// 動圖
UIImage *image = [UIImage animatedImageWithImages:images duration:INFINITY];

4.圖片解壓縮

圖片解壓縮是將解碼后的image解出bitmap,從而避免系統(tǒng)主線程解壓縮導致的主線程卡頓的問題。這里兩個庫也都是大同小異。以LKImageKit為例:

CGContextRef context = CGBitmapContextCreate(NULL, clipSize.width, clipSize.height, 8, 0, colorspace, bitmapInfo);
CGContextDrawImage(context, imageRect, input.CGImage);
CGImageRef cgimage = CGBitmapContextCreateImage(context);
UIImage *image = [UIImage imageWithCGImage:cgimage scale:screenScale orientation:input.imageOrientation];

不同的是,LKImageKit因為是用的指定的容器進行全鏈路的圖片加載,所以可以通過打通全鏈路,在解壓縮時,提前獲取加載的容器大小,然后根據(jù)容器的大小進行按需解bitmap,從而節(jié)約內(nèi)存。

開源SDWebImage并沒有這個優(yōu)化。我自己在SDWebImage上實現(xiàn)了一套類似的方案,需要從接口調(diào)用到解bitmap全鏈路打通,透傳容器大小按需解碼,以及對帶alpha通道的webp圖片等的異常case處理。略有不同的是,LKImageKit使用了image的scale屬性,SDWebImage的scale默認1,需要做額外的pt->px的轉(zhuǎn)換。后續(xù)有機會會把代碼提到開源倉庫。

0x2總結(jié)

兩種圖片方案有各自的業(yè)務場景和出發(fā)點,各有好處。

LKImageKit方案對圖片的管理能力更強,圖片加載的流程對于框架更加透明;SDWebImage方案更加靈活,尤其在5.0后,各種擴展性都非常好,LKImageKit的下載、解碼管理有明顯的借鑒SDWebImage的痕跡。另外,對于圖片的加載流程,LKImageKit更加細膩,比如請求合并,按需解bitmap。

同時,從商業(yè)角度看,微信、QQ等大型App,是需要對圖片加載全鏈路進行埋點監(jiān)控的,這種強勢掌控加載細節(jié)的LKImageKit方案,處理其這樣的需求更加便利。猜想騰訊內(nèi)部的LKImageKit版本應該還有埋點監(jiān)控、網(wǎng)絡接管等更多模塊的適配接口,開源的只是刪減了相關依賴的外部版本。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容