iOS SDWebImage 原始碼閱讀(一)

2021-07-22 16:20:55 字數 4449 閱讀 9327

這是我看的第四份比較著名的原始碼了,看了不只一遍,因為裡面蘊含的知識太多了,而且剛開始也有一些地方不懂,不過經過不斷的查資料等等終於是差不多理解了,下面就把我看的地方記錄下來,希望能對正在看這份**的人有所幫助,我會盡量的每一處地方都講到。老規矩,按照一次**呼叫的全程來分析。

首先看最常用的方法

/**

* set the imageview `image` with an `url`.

* * the download is asynchronous and cached.

* * @param url the url for the image.

*/- (void)sd_setimagewithurl:(nsurl *)url;

這裡只要傳入url即可。

但是整個框架有很多個初始化方法,如下:

- (void)sd_setimagewithurl:(nsurl *)url ;

- (void)sd_setimagewithurl:(nsurl *)url placeholderimage:(uiimage *)placeholder ;

- (void)sd_setimagewithurl:(nsurl *)url placeholderimage:(uiimage *)placeholder options:(sdwebimageoptions)options ;

- (void)sd_setimagewithurl:(nsurl *)url completed:(sdwebimagecompletionblock)completedblock ;

- (void)sd_setimagewithurl:(nsurl *)url placeholderimage:(uiimage *)placeholder completed:(sdwebimagecompletionblock)completedblock ;

- (void)sd_setimagewithurl:(nsurl *)url placeholderimage:(uiimage *)placeholder options:(sdwebimageoptions)options completed:(sdwebimagecompletionblock)completedblock ;

所有的這些初始化方法都呼叫了同乙個初始化方法:

- (void)sd_setimagewithurl:(nsurl *)url placeholderimage:(uiimage *)placeholder options:(sdwebimageoptions)options progress:(sdwebimage**********progressblock)progressblock completed:(sdwebimagecompletionblock)completedblock ;

這個叫做全能初始化方法,詳見effctive objective-c 2.0中的第16條,以後我們設計介面的時候也應該這麼設計。

if (!(options & sdwebimagedelayplaceholder)) );

}

先看這個判斷,它是這樣定義的

typedef ns_options(nsuinteger, sdwebimageoptions)

這是利用了二進位制,如果選定了這個選項,這個選項就被置為1.

然後在判斷裡用與操作就能得到是否是這個選項,好處是同乙個變數可以被賦予多重含義,且運算速度快。

這裡**的意義是placeholder是否要延遲,如果不延遲,馬上就把placeholder先放上去。

而且作者在這裡定義了乙個巨集,這個巨集的作用是,如果當前執行緒不是主線程,他會把**強制放到主線程中執行。

然後看下面的**

if ([self showactivityindicatorview])
如果使用者允許顯示activityindicatorview,那就新增乙個activityindicator.

下面講activityindicator的新增過程。

這塊其實是乙個lazy load

先判斷是否為空,如果不為空則直接開始動畫。

如果為空,則建立乙個,然後首先新增約束。

self.activityindicator.translatesautoresizingmaskintoconstraints = no;
這句,如果從**層面開始使用autolayout,需要把這個屬性設定為no。然後可以通過**新增約束。

[self addconstraint:[nslayoutconstraint constraintwithitem:self.activityindicator

attribute:nslayoutattributecenterx

relatedby:nslayoutrelationequal

toitem:self

attribute:nslayoutattributecenterx

multiplier:1.0

constant:0.0]];

[self addconstraint:[nslayoutconstraint constraintwithitem:self.activityindicator

attribute:nslayoutattributecentery

relatedby:nslayoutrelationequal

toitem:self

attribute:nslayoutattributecentery

multiplier:1.0

constant:0.0]];

以上是新增的約束,字面就可以理解。

然後。

__weak __typeof(self)wself = self;

這句話是為了防止迴圈引用。

之後用到了sdwebimagemanager這個單例類。

id operation = [[sdwebimagemanager sharedmanager] downloadimagewithurl:url options:options progress:progressblock completed:^(uiimage *image, nserror *error, sdimagecachetype cachetype, bool finished, nsurl *imageurl)

看一下這個類的初始化

- (instancetype)init

關於sdwebimageoperation這個協議我們先不管,包括operation都先放下,以後再說。

下面進入到上面那個downloadimagewithurl方法中去看一看。

if ([url iskindofclass:nsstring.class]) 

if (![url iskindofclass:nsurl.class])

如果使用者沒有傳入nsurl物件,而是傳了乙個字串進來,把它變成nsurl物件。

bool isfailedurl = no;

@synchronized (self.failedurls)

這是乙個失敗url的列表,並且加了鎖,防止多執行緒的問題。

這個與後面的sdwebimageretryfailed選項是有關係的。

if (url.absolutestring.length == 0 || (!(options & sdwebimageretryfailed) && isfailedurl)) );

return operation;

}

如果url的長度為0或者url是失敗的且不重試,則直接建立nserror並且直接completedblock。

這裡有乙個點,就是在程式中最好不好使用try catch,因為這很容易會造成記憶體洩漏,因為當程式發生錯誤返回的時候,會導致一些物件不能正常被釋放,所以最好用傳遞nserror的方式來報告錯誤。

nsstring *key = [self cachekeyforurl:url];

這裡,它對每乙個url做了快取,key就是url對應的字串,sdwebimage的快取也是根據這個key來找到對應的的。

這裡還有乙個對url的處理,需要手動設定,不看原始碼是不會發現的。

就是

[[sdwebimagemanager sharedmanager] setcachekeyfilter:^(nsurl *url) ];
你可以做乙個這樣的設定,就可以過濾掉url後面的引數,一般這些引數很長,可以節省記憶體。

AbstractCollection原始碼分析

abstractcollection抽象類提供了collection的骨架實現,collection分析請看 這裡直接看它的 是如何實現的.public abstract iterator iterator 該方法沒有實現.public abstract int size 該方法沒有實現.publi...

ThreadPoolExecutor原始碼閱讀

執行緒池解決兩個問題 一是復用執行緒,減少建立銷毀執行緒帶來系統開銷 二是限定系統資源使用邊界,避免大量執行緒消耗盡系統記憶體 適用於互不依賴,執行時間短,不需要對執行緒控制操作的執行緒 新增任務時,1.若執行緒數量小於corepoolsize,則新增執行緒執行任務 2.若執行緒數量大於等於core...

OrangePi One Android 原始碼編譯

一 系統環境搭建參照 二 lichee原始碼編譯 1.檢視help build.sh h2.配置核心 cd linux 3.4 make arch arm menuconfig 進入配置頁面,上下移動列表,空格是選擇列表,左右移動選擇退出選項 3.首次編譯執行清除 在 lichee linux3.4...