SDWebImage 源碼(一) sd_set系列方法

從UIImageView+WebCache看起~

一般來說俩莽,SD用的比較多的應(yīng)該就是這個(gè)category中的sd_set等一系列方法了进鸠。

下面咱們就一步步“CMD+點(diǎn)擊”進(jìn)去涮雷,一層層剖析吧~

/*

* url: 圖片URL

* placeholder: 占位圖片

* options: 加載圖片的選項(xiàng)(包括失敗重試、低優(yōu)先級(jí)、僅保存在緩存中掂咒、邊下載邊顯示、刷新緩存迈喉、進(jìn)入后臺(tái)繼續(xù)下載绍刮、保留Cookie、允許不信任的SSL證書挨摸、高優(yōu)先級(jí)孩革、延遲顯示占位圖片、改變動(dòng)畫形象)

* progressBlock 圖片下載過程中得运,每次接收到數(shù)據(jù)的回調(diào)的block

* completedBlock 圖片下載完成回調(diào)的block

*/

-(void)sd_setImageWithURL:(NSURL*)url placeholderImage:(UIImage*)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;

一膝蜈、sd_set內(nèi)首先執(zhí)行的是sd_cancelCurrentImageLoad锅移,用于取消當(dāng)前對(duì)象內(nèi)所有下載任務(wù)

// 取消當(dāng)前下載

[selfsd_cancelCurrentImageLoad];

SD會(huì)為每一個(gè)UIImageView對(duì)象拓展一個(gè)用于存放所有下載隊(duì)列的NSDictionary屬性,sd_cancelCurrentImageLoad方法內(nèi)饱搏,會(huì)遍歷NSDictionary對(duì)應(yīng)key的所有隊(duì)列非剃,取消下載任務(wù)。

二推沸、拓展屬性备绽,保存最新的url,并判斷當(dāng)前url是否為空

三鬓催、若url不為空肺素,則通過SDWebImageManager單例類來獲取下載隊(duì)列、取消所有下載任務(wù)宇驾,并將下載隊(duì)列保存

★SDWebImageManager中倍靡,根據(jù)key(將url通過MD5加密得到的字符串作為查詢緩存和沙盒文件名的key),先到緩存(NSCache)中查找飞苇;緩存查找不到菌瘫,再到沙盒中查找,若還找不到URL對(duì)應(yīng)的圖片的話布卡,則通過imageDownloader開啟下載任務(wù)(SDWebImageDownloader對(duì)象)雨让。

★SDWebImageDownloader中,有個(gè)URLCallbacks字典忿等,里面以URL為key栖忠,保存著對(duì)應(yīng)URL的接受數(shù)據(jù)回調(diào)和下載完成回調(diào)的block。開始下載之前贸街,會(huì)通過dispatch_barrier_sync在唯一的一個(gè)并發(fā)隊(duì)列中(barrierQueue)將block保存到URLCallbacks中庵寞。(當(dāng)URL已經(jīng)存在,則不會(huì)重復(fù)下載薛匪,只會(huì)更新回調(diào)block)捐川。該過程主要實(shí)現(xiàn)通過下面的方法:

-(void)addProgressCallback:(SDWebImageDownloaderProgressBlock)progressBlock andCompletedBlock:(SDWebImageDownloaderCompletedBlock)completedBlock forURL:(NSURL*)url createCallback:(SDWebImageNoParamsBlock)createCallback

★異步下載,通過SDWebImageDownloaderOperation實(shí)現(xiàn)(繼承自NSOperation逸尖,該操作隊(duì)列實(shí)現(xiàn)了SDWebImageOperation協(xié)議古沥,僅有一個(gè)取消下載的代理方法)。operation添加到任務(wù)隊(duì)列之前娇跟,根據(jù)options選項(xiàng)的高低優(yōu)先級(jí)以及LIFO(后進(jìn)先出原則)岩齿,來決定opeartion的優(yōu)先級(jí)以及設(shè)置隊(duì)列的依賴。

if(options&SDWebImageDownloaderHighPriority){

operation.queuePriority=NSOperationQueuePriorityHigh;

}elseif(options&SDWebImageDownloaderLowPriority){

operation.queuePriority=NSOperationQueuePriorityLow;

}

if(wself.executionOrder==SDWebImageDownloaderLIFOExecutionOrder){

// Emulate LIFO execution order by systematically adding new operations as last operation's dependency

[wself.lastAddedOperation addDependency:operation];

wself.lastAddedOperation=operation;

}

1.在start中苞俘,利用NSURLConnection來請(qǐng)求圖片數(shù)據(jù)盹沈,通過實(shí)現(xiàn)代理方法來判斷圖片開始下載、下載中吃谣、下載成功乞封、失敗做裙。此外,在start最初時(shí)歌亲,判斷options參數(shù)菇用,若需要后臺(tái)下載,則申請(qǐng)后臺(tái)任務(wù)陷揪。

#if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0

ClassUIApplicationClass=NSClassFromString(@"UIApplication");

BOOL hasApplication=UIApplicationClass&&[UIApplicationClassrespondsToSelector:@selector(sharedApplication)];

if(hasApplication&&[selfshouldContinueWhenAppEntersBackground]){

__weak __typeof__(self)wself=self;

UIApplication*app=[UIApplicationClassperformSelector:@selector(sharedApplication)];

self.backgroundTaskId=[app beginBackgroundTaskWithExpirationHandler:^{

__strong __typeof(wself)sself=wself;

if(sself){

[sself cancel];

[app endBackgroundTask:sself.backgroundTaskId];

sself.backgroundTaskId=UIBackgroundTaskInvalid;

}

}];

}

#endif

2.在NSURLConnection的代理方法 didRecieveData中惋鸥,判斷options選項(xiàng),是否需要邊下載邊顯示悍缠,該功能通過CoreGraphics實(shí)現(xiàn)卦绣。并且回調(diào)下載進(jìn)度的block。

3.在NSURLConnection的代理方法 connectionDidFinishLoading中飞蚓,停止當(dāng)前runloop滤港。同時(shí)根據(jù)URL中是否包含@2x,@3x字段來進(jìn)行相應(yīng)縮放以及進(jìn)行圖片解碼趴拧。并且回調(diào)block溅漾。

★回調(diào)過程:SDWebImageDownloaderOperation –(通過block回調(diào))–>SDWebImageDownloader –(通過URLCallBacks字典獲取回調(diào)block回調(diào))–>SDWebImageManager。SDWebImageManager的回調(diào)block中著榴,通過一個(gè)SDImageCache的屬性添履,實(shí)現(xiàn)了圖片緩存的操作。

1.通過SDImageCache將圖片緩存到內(nèi)存及沙盒脑又。(期間還會(huì)有其他操作暮胧,如根據(jù)options判斷是否僅緩存到內(nèi)存)。圖片緩存主要通過下面的方法

[self.imageCache storeImage:downloadedImage recalculateFromImage:NO imageData:data forKey:key toDisk:cacheOnDisk];

2.程序進(jìn)入后臺(tái)或者結(jié)束時(shí)问麸,SDImageCache都會(huì)清理內(nèi)存往衷。主要操作包括移除過期文件、將緩存保持在最大緩存的一半严卖。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末席舍,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子哮笆,更是在濱河造成了極大的恐慌俺亮,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疟呐,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡东且,警方通過查閱死者的電腦和手機(jī)启具,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來珊泳,“玉大人鲁冯,你說我怎么就攤上這事拷沸。” “怎么了薯演?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵撞芍,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我跨扮,道長(zhǎng)序无,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任衡创,我火速辦了婚禮帝嗡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘璃氢。我一直安慰自己哟玷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布一也。 她就那樣靜靜地躺著巢寡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪椰苟。 梳的紋絲不亂的頭發(fā)上抑月,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音尊剔,去河邊找鬼爪幻。 笑死,一個(gè)胖子當(dāng)著我的面吹牛须误,可吹牛的內(nèi)容都是我干的挨稿。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼京痢,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼奶甘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起祭椰,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤臭家,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后方淤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钉赁,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年携茂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了你踩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖带膜,靈堂內(nèi)的尸體忽然破棺而出吩谦,到底是詐尸還是另有隱情,我是刑警寧澤膝藕,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布式廷,位于F島的核電站,受9級(jí)特大地震影響芭挽,放射性物質(zhì)發(fā)生泄漏滑废。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一览绿、第九天 我趴在偏房一處隱蔽的房頂上張望策严。 院中可真熱鬧,春花似錦饿敲、人聲如沸妻导。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽倔韭。三九已至,卻和暖如春瓢对,著一層夾襖步出監(jiān)牢的瞬間寿酌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工硕蛹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留醇疼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓法焰,卻偏偏與公主長(zhǎng)得像秧荆,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子埃仪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

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