SDWebImage源碼解析

SDWebImage是我們非常常用的一個關(guān)于圖片下載緩存的框架婶希。下面的源碼分析是基于版本3.8。下面是gitHub上的介紹:

主要作用:

1仆救、為UIiamgeView,UIbutton? 等控件加載網(wǎng)絡(luò)圖片拯杠,并且進行緩存管理

2翅萤、一個異步圖片下載工具

3其骄、一個異步的內(nèi)存和硬盤的圖片緩存亏镰,提供自動的緩存處理

4、異步的圖片解碼

5拯爽、保證相同的URL不會多次下載

6索抓、保證不合法的URL不會被多次下載

7、保證主線程不會被阻塞

8毯炮、自定義

9逼肯、使用GCD 和 ARC

為什么使用SDWebImage而不是NSURLCache或是AFN?

1桃煎、在IOS 5之后可以使用NSURLCache 進行http緩存篮幢,但是每次緩存的是原始數(shù)據(jù),每一次使用的時候为迈,需要將原始數(shù)據(jù)解析成UIImage三椿,導(dǎo)致額外的數(shù)據(jù)解析和內(nèi)存占用,AFN就是使用NSURLCache進行緩存的葫辐。

2搜锰、UIImageView中使用image對象的時候,圖片的解碼是在主線程中運行的耿战!而SDWebImage會強制將解碼操作放到子線程中蛋叼。(PNG,jpeg圖片對象剂陡,轉(zhuǎn)換為位圖對象)

3狈涮、使用NSCache作為內(nèi)存緩存,避免了對象的重復(fù)copy鸭栖,并且保存的是位圖對象薯嗤,避免了重復(fù)的解碼。

4纤泵、SDWebImage 完全繞過了Http請求關(guān)于緩存的控制骆姐,大大加快了緩存速度。

根據(jù)圖片的url緩存捏题,所以一旦改變圖片玻褪,必須改變地址?(不會去判斷服務(wù)器關(guān)于緩存處理的response header )對于類似facebook 頭像這樣的例子公荧,可以使用下面的方式带射,這種方式,會參考請求頭循狰。

5窟社、提供了大量的關(guān)于圖片的擴展選擇券勺。

當(dāng)我們調(diào)用這個sd_setImageWithURL,這個方法的時候發(fā)生了什么灿里?

1关炼、停止所有和這個View相關(guān)的Operation。

這里還有一個operation 字典:UIView+WebCacheOperation ?有一個關(guān)聯(lián)對象匣吊,用來保存這個View相關(guān)的Operation


operation字典


UIView+WebCacheOperation的cancle 當(dāng)前所有相關(guān)的Operation

(相關(guān)類的介紹:

UIImageView (WebCache):

1儒拂、提供相關(guān)的下載方法

UIView (WebCacheOperation)

1、提供與view相關(guān)的loadOperation(字典),可以通過這個字典取消該View相關(guān)的Operation)

2色鸳、SDWebImageManager的downloadImageWithURL的方法

(1)社痛、非法Url判斷

(2)、定義一個SDWebImageCombinedOperation命雀,用這個Operation管理下載和緩存的Operation蒜哀,并把它加到runningOperations中

(3)、產(chǎn)生緩存的key吏砂,這里的緩存的key凡怎,可以進行自定義


自定義緩存key

(相關(guān)類介紹:

SDWebImageOperation

1、定義的一個基礎(chǔ)協(xié)議赊抖,帶有cancle方法

SDWebImageCombinedOperation

1统倒、混合Operation,包含緩存Operation還有管理下載Operation

SDWebImageManager

SDWebImageManager(單例)

1氛雪、中間層房匆,調(diào)用緩存,和下載(管理所有的Operation)

2报亩、提供SDWebImageManagerDelegate(作為擴展)浴鸿,還有三種block

)

3、SDImageCache的queryDiskCacheForKey方法弦追,開始尋找磁盤緩存和內(nèi)存緩存

(1)岳链、內(nèi)存緩存,使用的NSCache(避免重復(fù)拷貝)

(2)劲件、一個IOQueue,進行磁盤緩存的查詢,進行異步查詢


在io隊列里面異步查詢

(3)掸哑、如果磁盤中存在這張圖片,那么進行判斷對應(yīng)的圖片格式(包括動態(tài)圖)

設(shè)置圖片的方向(Orientation)零远,scale苗分,并且進行解碼工作。這里強制進行異步解碼牵辣,將編碼之后的圖片格式(png摔癣,jpeg)轉(zhuǎn)換成位圖對象。


進行緩存查找操作

相關(guān)的類:

SDImageCache(單例)

1、緩存管理择浊,緩存配置戴卜,緩存清理,緩存查找(異步執(zhí)行)

2琢岩、內(nèi)存緩存投剥,使用的是位圖,磁盤緩存使用的是編碼之后的圖片

UIImage (ForceDecode)

1粘捎、圖片解碼薇缅,相關(guān)格式圖片圖像危彩,轉(zhuǎn)換為位圖對象

強制解碼:將編碼之后的image對象轉(zhuǎn)換為位圖(點陣圖像或繪制圖像攒磨,是由稱作像素(圖片元素)的單個點組成的)

一般下載或者從磁盤獲取的圖片是PNG或者JPG,這是經(jīng)過編碼壓縮后的圖片數(shù)據(jù)汤徽,不是位圖娩缰,要把它們渲染到屏幕前就需要進行解碼轉(zhuǎn)成位圖數(shù)據(jù),而這個解碼操作比較耗時谒府,iOS默認是在主線程解碼拼坎,所以SDWebImage將這個過程放到子線程了。

同時因為位圖體積很大完疫,所以磁盤緩存不會直接緩存位圖數(shù)據(jù)泰鸡,而是編碼壓縮后的PNG或JPG數(shù)據(jù)。

4壳鹤、當(dāng)沒有緩存時候盛龄,使用SDWebImageDownloader進行下載,

(1)芳誓、將所有的callback放在一個字典數(shù)組中管理余舶。(用url作為key)。

(2)锹淌、封裝request對象匿值,加入用戶自帶的一些配置

注:為了避免重復(fù)下載,默認赂摆,不進行NSUrlCache緩存挟憔,不使用系統(tǒng)的緩存


避免重復(fù)下載

(3)產(chǎn)生SDWebImageDownloaderOperation,下載操作

(4)設(shè)置這個operation 的相關(guān)屬性烟号,比如優(yōu)先級曲楚,還有executionOrder,執(zhí)行順序(先進后出或是先進先出)褥符,(實現(xiàn)的方式龙誊,是通過Operation的相互依賴)


關(guān)于執(zhí)行順序的枚舉值
執(zhí)行順序設(shè)定的實現(xiàn)

相關(guān)的類:

SDWebImageDownloader

1、圖片下載類喷楣,圖片的下載管理

2趟大、提供大量擴展(下載設(shè)置)

SDWebImageDownloaderOptions

SDWebImageDownloaderExecutionOrder鹤树,下載的順序

SDWebImageDownloaderProgressBlock

SDWebImageDownloaderCompletedBlock

SDWebImageDownloaderHeadersFilterBlock

maxConcurrentDownloads(最大并發(fā)數(shù))

3、操作callBack使用的的調(diào)度方式逊朽, dispatch_barrier_sync罕伯,dispatch_barrier_async管理barrierQueue(類似于鎖?),之后添加的Operation叽讳,會等這個任務(wù)執(zhí)行之后才會繼續(xù)執(zhí)行

5追他、使用SDWebImageDownloaderOperation,進行下載岛蚤,在下載過程中邑狸,調(diào)用progressBlock,下載結(jié)束涤妒,調(diào)用completeBlock贵扰。拿到網(wǎng)絡(luò)數(shù)據(jù)齿诉,轉(zhuǎn)成圖片格式壹若,設(shè)置方向屿讽,scale,進行圖片解碼贿讹,返回的圖片是位圖對象

管理下載操作渐逃,3版本使用的是NSURLConnection,之后使用的是NSURLSession(異步下載)

(1)民褂、提供后臺下載茄菊,開啟運行循環(huán)(不然代理不能正常調(diào)用)

(2)在NSURLConnection的代理中,處理下載功能

(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 拿到服務(wù)器響應(yīng)助赞,判斷是否正確下載

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data下載過程管理(調(diào)用progressBlock)买羞,這里提供邊下載,邊顯示的功能

下載圖片雹食,進行異步的強制解碼

6畜普、回到SDWebImageManager,

(1)處理Image對象群叶,如果實現(xiàn)了相關(guān)的代理方法就調(diào)用代理方法吃挑,

(2)之后使用imageCache,保存圖片信息街立。位圖對象直接保存到內(nèi)存緩存中舶衬,編碼圖片,保存到磁盤中赎离。(這里是否能在之前就直接保存到磁盤逛犹,節(jié)省一段圖片編碼的過程)。內(nèi)存中保存位圖虽画,是為了避免重復(fù)解碼舞蔽。磁盤中保存編碼之后的圖片是為了節(jié)省空間码撰。

(3)從全局的Operation字典朵栖,移除相關(guān)的Operation


將下載后的圖片進行緩存

7、回到UIImageView (WebCache)狠鸳,回到主線程件舵,設(shè)置圖片卸察,調(diào)用結(jié)束


更新UI,回到主線程

其他注意的點:

1铅祸、緩存清理坑质,當(dāng)收到這三個通知的時候進行緩存的清理


緩存清理的策略,這里的IO操作都是異步處理的临梗。

(1)刪除過期緩存(蘋果官方規(guī)定最長的緩存周期是1周)

(2)計算當(dāng)前緩存文件的總大小,比較設(shè)置的最大緩存,如果超出的話,那么就繼續(xù)刪除(按照緩存文件創(chuàng)建的順序),直到小于最大緩存為止


緩存策略

2涡扼、SDWebImagePrefetcher,這個類盟庞,提供提前緩存圖片的方法(可以用來作用于banner等)吃沪,提供批量的下載。


3什猖、對于UIView (WebCacheOperation)票彪,當(dāng)我們移除Operation的時候,發(fā)生了什么不狮?其實取消的是SDWebImageCombinedOperation

(1)降铸、取消cacheOperation

(2)、執(zhí)行cancelBlock,這里的cancleBlock摇零,關(guān)閉的就是下載的Operation

(3)推掸、將這個Operation,移除整個Operation字典



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市谅畅,隨后出現(xiàn)的幾起案子俊嗽,更是在濱河造成了極大的恐慌,老刑警劉巖铃彰,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绍豁,死亡現(xiàn)場離奇詭異,居然都是意外死亡牙捉,警方通過查閱死者的電腦和手機竹揍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來邪铲,“玉大人芬位,你說我怎么就攤上這事〈剑” “怎么了昧碉?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長揽惹。 經(jīng)常有香客問我被饿,道長,這世上最難降的妖魔是什么搪搏? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任狭握,我火速辦了婚禮,結(jié)果婚禮上疯溺,老公的妹妹穿的比我還像新娘论颅。我一直安慰自己,他們只是感情好囱嫩,可當(dāng)我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布恃疯。 她就那樣靜靜地躺著,像睡著了一般墨闲。 火紅的嫁衣襯著肌膚如雪今妄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天损俭,我揣著相機與錄音蛙奖,去河邊找鬼。 笑死杆兵,一個胖子當(dāng)著我的面吹牛雁仲,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播琐脏,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼攒砖,長吁一口氣:“原來是場噩夢啊……” “哼缸兔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起吹艇,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤惰蜜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后受神,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抛猖,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年鼻听,在試婚紗的時候發(fā)現(xiàn)自己被綠了财著。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡撑碴,死狀恐怖撑教,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情醉拓,我是刑警寧澤伟姐,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站亿卤,受9級特大地震影響愤兵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜怠噪,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一恐似、第九天 我趴在偏房一處隱蔽的房頂上張望杜跷。 院中可真熱鬧傍念,春花似錦、人聲如沸葛闷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽淑趾。三九已至阳仔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間扣泊,已是汗流浹背近范。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留延蟹,地道東北人评矩。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像阱飘,于是被迫代替她去往敵國和親斥杜。 傳聞我的和親對象是個殘疾皇子虱颗,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,500評論 2 359

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