[iOS/OC]SDWebImage和LKImage對(duì)比

0x0背景

原本是放到自己博客的席楚,不怎么用了凭需,把文章同步過(guò)來(lái)染乌,原文地址[iOS/OC]SDWebImage和LKImage對(duì)比

LKImageKit是騰訊開(kāi)源的一個(gè)高性能圖片加載框架瘫辩,雖然第一時(shí)間下載了源碼伏嗜,但是只是簡(jiǎn)單的看了框架,沒(méi)有細(xì)致的研讀源碼伐厌。最近空閑下來(lái)承绸,學(xué)習(xí)了一下LKImageKit源碼,其中有很多巧妙的實(shí)現(xiàn)挣轨。本文將通過(guò)1張圖片的加載流程军熏,對(duì)比兩個(gè)圖片框架。

0x1正文

LKImageKit和SDWebImage分別選用了兩種不同的圖片加載方案卷扮。LKImageKit的圖片加載是提供了一個(gè)LKImageView荡澎,加載圖片需要使用指定的容器。SDWebImage是寫(xiě)了一個(gè)Category画饥,加載圖片可以使用系統(tǒng)的UIImageView或其子類(lèi)衔瓮。流程上。

1.入口

發(fā)起一個(gè)圖片加載抖甘,LKImageKit是在layoutSubviews時(shí)热鞍,發(fā)起1次圖片加載,SDWebImage提供了1個(gè)主動(dòng)發(fā)起圖片加載請(qǐng)求的接口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:@""]];

// 之后開(kāi)始下載流程

兩個(gè)圖片庫(kù)都提供了加載回調(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進(jìn)行圖片下載會(huì)統(tǒng)一由LKImageManger進(jìn)行管理艰额,LKImageKit提供的請(qǐng)求合并的優(yōu)化就是通過(guò)LKImageManager進(jìn)行的澄港。請(qǐng)求會(huì)通過(guò)blockOperation放到1個(gè)operationQueue中進(jìn)行多個(gè)加載請(qǐng)求的隊(duì)列管理。

資源加載則由LKImageLoader進(jìn)行柄沮,由單例LKImageLoaderManager進(jìn)行管理回梧。網(wǎng)絡(luò)下載是LKImageNetworkFileLoader進(jìn)行废岂,使用了NSURLSession,本地圖片加載通過(guò)LKImageLocalFileLoader進(jìn)行狱意。

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

SDWebImage進(jìn)行圖片下載由SDWebImageManager進(jìn)行管理湖苞。類(lèi)似的,在SDWebImage 5.0版本開(kāi)始详囤,也使用SDWebImageLoader進(jìn)行加載财骨,使用SDWebImageLoadersManager進(jìn)行管理。網(wǎng)絡(luò)下載使用SDWebImageDownloader進(jìn)行藏姐。使用NSOperation進(jìn)行下載管理隆箩。

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

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

3.圖片解碼

LKImageKit和SDWebImage的圖片解碼大同小異,以L(fǎng)KImageKit為例:

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

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

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

// 動(dòng)圖
UIImage *image = [UIImage animatedImageWithImages:images duration:INFINITY];

4.圖片解壓縮

圖片解壓縮是將解碼后的image解出bitmap护姆,從而避免系統(tǒng)主線(xiàn)程解壓縮導(dǎo)致的主線(xiàn)程卡頓的問(wèn)題矾端。這里兩個(gè)庫(kù)也都是大同小異。以L(fǎng)KImageKit為例:

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因?yàn)槭怯玫闹付ǖ娜萜鬟M(jìn)行全鏈路的圖片加載秩铆,所以可以通過(guò)打通全鏈路,在解壓縮時(shí)灯变,提前獲取加載的容器大小殴玛,然后根據(jù)容器的大小進(jìn)行按需解bitmap,從而節(jié)約內(nèi)存添祸。

開(kāi)源SDWebImage并沒(méi)有這個(gè)優(yōu)化滚粟。我自己在SDWebImage上實(shí)現(xiàn)了一套類(lèi)似的方案,需要從接口調(diào)用到解bitmap全鏈路打通刃泌,透?jìng)魅萜鞔笮“葱杞獯a凡壤,以及對(duì)帶alpha通道的webp圖片等的異常case處理。略有不同的是耙替,LKImageKit使用了image的scale屬性亚侠,SDWebImage的scale默認(rèn)1,需要做額外的pt->px的轉(zhuǎn)換俗扇。后續(xù)有機(jī)會(huì)會(huì)把代碼提到開(kāi)源倉(cāng)庫(kù)硝烂。

0x2總結(jié)

兩種圖片方案有各自的業(yè)務(wù)場(chǎng)景和出發(fā)點(diǎn),各有好處铜幽。

LKImageKit方案對(duì)圖片的管理能力更強(qiáng)滞谢,圖片加載的流程對(duì)于框架更加透明串稀;SDWebImage方案更加靈活,尤其在5.0后狮杨,各種擴(kuò)展性都非常好厨诸,LKImageKit的下載、解碼管理有明顯的借鑒SDWebImage的痕跡禾酱。另外,對(duì)于圖片的加載流程绘趋,LKImageKit更加細(xì)膩颤陶,比如請(qǐng)求合并,按需解bitmap陷遮。

同時(shí)滓走,從商業(yè)角度看,微信帽馋、QQ等大型App搅方,是需要對(duì)圖片加載全鏈路進(jìn)行埋點(diǎn)監(jiān)控的,這種強(qiáng)勢(shì)掌控加載細(xì)節(jié)的LKImageKit方案绽族,處理其這樣的需求更加便利姨涡。猜想騰訊內(nèi)部的LKImageKit版本應(yīng)該還有埋點(diǎn)監(jiān)控、網(wǎng)絡(luò)接管等更多模塊的適配接口吧慢,開(kāi)源的只是刪減了相關(guān)依賴(lài)的外部版本涛漂。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市检诗,隨后出現(xiàn)的幾起案子匈仗,更是在濱河造成了極大的恐慌,老刑警劉巖逢慌,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悠轩,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡攻泼,警方通過(guò)查閱死者的電腦和手機(jī)火架,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)忙菠,“玉大人距潘,你說(shuō)我怎么就攤上這事≈桓椋” “怎么了音比?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)氢惋。 經(jīng)常有香客問(wèn)我洞翩,道長(zhǎng)稽犁,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任骚亿,我火速辦了婚禮已亥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘来屠。我一直安慰自己虑椎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布俱笛。 她就那樣靜靜地躺著捆姜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪迎膜。 梳的紋絲不亂的頭發(fā)上泥技,一...
    開(kāi)封第一講書(shū)人閱讀 50,050評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音磕仅,去河邊找鬼珊豹。 笑死,一個(gè)胖子當(dāng)著我的面吹牛榕订,可吹牛的內(nèi)容都是我干的店茶。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼劫恒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼忽妒!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起兼贸,我...
    開(kāi)封第一講書(shū)人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤段直,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后溶诞,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體鸯檬,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年螺垢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了喧务。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡枉圃,死狀恐怖功茴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情孽亲,我是刑警寧澤坎穿,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響玲昧,放射性物質(zhì)發(fā)生泄漏栖茉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一孵延、第九天 我趴在偏房一處隱蔽的房頂上張望吕漂。 院中可真熱鬧,春花似錦尘应、人聲如沸惶凝。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)苍鲜。三九已至,卻和暖如春娜饵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背官辈。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工箱舞, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人拳亿。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓晴股,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親肺魁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子电湘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容