透徹理解block中weakSelf和strongSelf

? ? ?對于block的循環(huán)引用導(dǎo)致的內(nèi)存泄露,網(wǎng)上的講解文章很多,大部分說的都非常的好,但是描述的更為通俗直白的不多,本文意在通俗直白的解釋block循環(huán)引用導(dǎo)致的內(nèi)存泄露,以及為什么weakSelf與strongSelf這種官方提供的寫法的必要性.(雖然這種重寫為c++語法的過程被拋棄了,但是也可以作為學(xué)習(xí)的途徑)

結(jié)合下面一段代碼來看:

為什么會循環(huán)引用了呢?

其一:當(dāng)前對象強(qiáng)引用著blockTest,這句話很好理解,說白了也就是說當(dāng)前的對象self在內(nèi)存中不釋放,那么blockTest作為self的屬性也不會釋放.

其二:根據(jù)block捕捉上下文變量的原理,block內(nèi)部使用了self,那么將對self強(qiáng)引用.

大部分的解釋到此為止了,明白的人看到這里也沒什么疑惑可是作為尋求答案的不明白的同學(xué)來說,看上去還是似懂非懂,不透徹.那么接下來將多舉例子,從OC重寫到C++代碼層面分析一下這個問題.

首先,內(nèi)存不會被釋放也就是retainCount值不為0,這個道理始終是最基本的,單一變量控制,我們始終只在main函數(shù)中執(zhí)行這樣一句代碼,所以在main函數(shù)大括號內(nèi)代碼走完之前,self的retainCount值是1,blockTest的retainCount也是1,可是由于blockTest強(qiáng)引用了self導(dǎo)致self的retainCount增加了1變?yōu)?,當(dāng)main函數(shù)大括號走完后,self的retainCount減小到1,blockTest的retainCount還是1,self的retainCount沒有回到0,所以self此時和blockTest組成的引用關(guān)系,如同兩條蛇,咬住了對方的尾巴,誰也不松口,死鎖了!

當(dāng)我自己理解到這個節(jié)點的時候,我還是疑惑,block怎么就強(qiáng)引用了呢?為啥用 __weak __typeof(self) weakSelf = self;在block內(nèi)部使用weakSelf就不會強(qiáng)引用呢?為啥要 __strong __typeof(self) strongSelf = weakSelf;才會安全呢?這一系列的機(jī)理到底是怎么回事呢?

比較著咱們來思考一下,先把上面的代碼做一個改動

運行后斷點肯定會進(jìn),也就是內(nèi)存確實釋放了,weakSelf 是個局部變量,這個局部變量會被block捕獲,我們看一下這個使用weakSelf后的中間代碼

1==>表示的是blockTest的結(jié)構(gòu)體形式的表示,這部分中間代碼的具體含義不解釋了,網(wǎng)上有很多講解,

2==>表示的是blockTest的函數(shù)體,無論如何最終執(zhí)行的代碼功能片段都會是個函數(shù),block也不例外

3==>表示的就是- (void)test這個函數(shù).

核心的地方在于1和2,代碼執(zhí)行起來無非就是發(fā)消息,函數(shù)調(diào)用,傳遞參數(shù),返回值,這一系列的動作,

方法執(zhí)行起來以后,3開始執(zhí)行,調(diào)用到了2,2呢有這樣一句話__cself->weakSelf; 看2的形參__cself,其實是結(jié)構(gòu)體__WYTestObject__test_block_impl_0,而結(jié)構(gòu)體就是blockTest,用這種寫法__cself->weakSelf; 具體的編譯以及執(zhí)行肯定是更為細(xì)致精密,但是我們不難看出結(jié)構(gòu)體把weakSelf作為了自己的屬性,或者說直接捕獲的是weakSelf這個局部變量作為自己的屬性,但是可以通俗直白的理解為結(jié)構(gòu)體直接引用了weakSelf內(nèi)存空間想使用weakself中保存的self指針,而這個weakSelf并沒有增加self的引用計數(shù),所以self依然可以釋放.如果說這樣就砍斷了循環(huán)引用,那么蘋果為什么要提倡weak,strong寫法呢?請看下面的代碼

類似以上的情況我們不會總遇到,因此很多人都是只寫一個weakSelf在使用著,但是這樣崩潰的情況在更復(fù)雜的情況下,如果隱藏為nil的邏輯很深的話,出現(xiàn)不必現(xiàn)的bug就不好調(diào)試了.那么咱們在回到簡單的oc代碼中分析一下strongSelf寫法為什么既能避免這種為空情況,又能不產(chǎn)生循環(huán)引用的呢?請看下面的代碼.

只是多了箭頭所指的一句代碼,咱們看看中間代碼是此時又是什么樣的.

相比之前沒加入strongSelf的時候函數(shù)__WYTestObject__test_block_func_0 多了一句話WYTestObject * strongSelf = ?weakSelf,strongSelf賦值得到的是self(由weakSelf傳過來的),這使得在函數(shù)體運行期間self是不會被釋放的,__WYTestObject__test_block_func_0函數(shù)實際上就是blockTest的功能模塊,實際上執(zhí)行blockTest也就是在執(zhí)行__WYTestObject__test_block_func_0這個函數(shù),既然是函數(shù),那么大括號走完其函數(shù)體重的局部變量就會被釋放,也就是說函數(shù)執(zhí)行完以后,strongSelf作為局部變量正常釋放了,strongSelf也不屬于blockTest結(jié)構(gòu)體的屬性,weakSelf與strongSelf一內(nèi)一外,意義是不一樣的,所以下面的代碼:

以上代碼viewWy既能正常釋放,又不會崩潰,這也就是weak和strong配合使用的意義所在.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,362評論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,013評論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,346評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,421評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,146評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,534評論 1 325
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,585評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,767評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,318評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,074評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,258評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,828評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,486評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,916評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,156評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,993評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,234評論 2 375

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