weakSelf 和 strongSelf

最近在看 AFNetworking 和 SDWebImage源碼,碰到一些比較繞的問題,理解了好久,而後在網上查了些的資料,纔算是有了一些理解。在此記錄一下。git

AFNetworking 源碼以下:github

 

SDWebImage 源碼以下:多線程

 

block會copy要在block中使用的實變量,而copy會是變量的retainCount + 1,如若在不注意很容易形成循環引用。async

而所謂的循環引用的本質就是,兩個對象相互引用,從而形成對象不能正常的dealloc。spa

因此解決的辦法就是讓引用的一方是weak的,這樣就使得相互引用的閉環被打破,可以正常的dealloc了。.net

 

1)weakSelf的使用:線程

Apple 官方的建議是,傳進 Block 以前,把 ‘self’ 轉換成 weak automatic 的變量,這樣在 Block 中就不會出現對 self 的強引用。 3d

上圖的代碼中,backgroundTaskId是當前這個類的一個屬性,在backgroundTaskId初始化的這個方法中,有一個block回調,在這個block的實現中訪問須要訪問Self,爲了不形成循環引用,此處給當前的Self取了個別名,並用__weak來修飾,目的是告訴編譯器,此處是弱引用,不要retain 當前的這個類,也就是所謂的self。code

2)爲何會出現strongSelf?對象

Apple 官方文檔有講到,若是在 Block 執行完成以前,self 被釋放了,weakSelf 也會變爲 nil。

clang給出的實例代碼:

 

   __weak __typeof__(self) weakSelf = self;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        [weakSelf doSomething];

    });

 

 clang 的文檔表示,在 doSomething 內,weakSelf 不會被釋放。可是下面的狀況除外:

    __weak __typeof__(self) weakSelf = self;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        [weakSelf doSomething];

        [weakSelf doOtherThing];

    });

   在 doSomething 中,weakSelf 不會變成 nil,不過在 doSomething 執行完成,調用第二個方法 doOtherThing 的時候,weakSelf 有可能被釋放,

 

   因而,strongSelf 就派上用場了:

    __weak __typeof__(self) weakSelf = self;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        __strong __typeof(self) strongSelf = weakSelf;

        [strongSelf doSomething];

        [strongSelf doOtherThing];

    });

   __strong 確保strongSelf在block中不會被釋放

 

 

因此就能理解SDWebImage中的那段代碼,block在實現的過程當中會對wself進行一次強引用,是爲了防止在block還未執行完畢,wself在其餘線程中被釋放,使得wself爲nil。

 

 簡單的作個小結:

 一、在使用block時,若是block內部須要訪問self的方法、屬性、或者實例變量應當使用weakSelf

 二、若是在block內須要屢次訪問self,則須要使用strongSelf

 三、若是在block內部存在多線程環境訪問self,則須要使用strongSelf

 四、block自己不存在多線程之分,block執行是不是多線程,取決於當前的持有者是不是以多線程的方式來調用它。

 

 

clang的文檔連接

https://github.com/CoderBeta/clang-user-manual

http://blog.csdn.net/bbmb_mb/article/details/50470802

相關文章
相關標籤/搜索