喜欢用Block的值得注意-Block的Retain Cycle的解决方法
本文不講block如何聲明及使用,只講block在使用過程中暫時遇到及帶來的隱性危險。
主要基于兩點進行演示:
1.block 的循環引用(retain cycle)
2.去除block產生的告警時,需注意問題。
有一次,朋友問我當一個對象中的block塊中的訪問自己的屬性會不會造成循環引用,我哈綽綽的就回了一句,不會。兄弟,看完這個,希望你能理解我為什么會說不會循環引用。別廢話,演示開始。
下面是我專們寫了一個類來演示:
頭文件.h
[objc]?view plaincopy
實現文件
[objc]?view plaincopy
上面是因為考慮到在ARC 和非ARC中進行編譯演示,所以我特意加了ARC預編譯判斷。主要是方便不要改動太多的代碼來給大家演示。
在非ARC環境下
執行下在語句的測試:
[objc]?view plaincopy
輸出結果:
[cpp]?view plaincopy
很顯然。盡管demo 是局部變量,并autorelease但可以看出自然至終并沒有得到釋放,這是因為block中使用了 block內進行訪問了自身的resultCode屬性。相信很多朋友也都會解決這種循環引用問題。就是在變量前面加個__block,就像這樣。
[objc]?view plaincopy
好下面再來看一下在ARC模式下的block循環引用又是怎么樣的。
在ARC模式下
執行下面語句:
[cpp]?view plaincopy
執行輸出結果:
[objc]?view plaincopy
相信看到這里的人,大多都要噴了,這哪個不知道呀,還知道怎么解決呢,非ARC中加了個__block,當然的在ARC中加一個__weak就搞定了。嗯,確實是這樣,但別急,接著往下看,絕對有收獲。在這里先自己默認想一下,你是如何加這個__weak的。
對于第一個問是點block 的循環引用(retain cycle)到這里暫告結束。下面講第二點。因為block告警在非ARC 中暫未發現因寫法引入(如果你知道,麻煩告訴我怎么弄產生告警,我好研究一下。)
下面講在ARC模式下去除因寫法產生的告警時需要注意的問題。
像上面的寫法其實在ARC中會產生(Capturing 'demo' strongly in this block is likely to lead to a retain cycle)告警。如下圖:
在ARC中,編譯器智能化了,直接提示這樣寫會產生循環引用。因此很多愛去除告警的朋友就會想法去掉,好,咱再來看去掉時需注意的問題。
情況一:
[objc]?view plaincopy
這時還會告警,說這是一個WEAK變量,就馬上會被release。因此就不會執行block中的內容。大家可以運行一下看
輸出結果為:
[cpp]?view plaincopy
謝天謝地,幸好編譯器提前告訴了我們有這個隱性危險。相信大家為解決告警,又會得到一個比較圓滿的解決方案,見下:
[objc]?view plaincopy
這樣寫,即去除了告警又保證了block的運行。這才是我們最終想要的結果。
輸出為:
[cpp]?view plaincopy
但大家別得意。有提示,相信大家都能處理,并得到個好的解決方法。哪么下面大來再來看一下這個寫法,讓你真心甘拜下風。。。。。
[objc]?view plaincopy
[objc]?view plaincopy
直接輸出:
[cpp]?view plaincopy
因此,寫這個主要用來告戒一些喜歡用BLOCK但又想當然的朋友,有一些朋友喜歡去除告警,但只是盲目的加上__weak 或__block關鍵語,往往可能存在一些重大的安全隱患。就像演示中block根本不走。如果到了發布時,為了去告警而這樣簡單的處理了,并沒有進行測試就打包。哪么將死得很慘。。。。。
好,到了尾聲,來說說為什么朋友問我block會不會引行死循環,我說不會的理由。
見碼:
[objc]?view plaincopy
不管是在外面init,還是在里面,且沒有加__block 及__weak。為什么,因為我個人常常在使用自己寫的block時,如果是回調,比較喜歡把自身當作參數傳到block中。這樣期實是編譯器給我們做了弱引用。因此不會產生循環引用。
由于我一直都這樣寫block,所以朋友一問起,我就說不會循環引用了,因為壓根他碰到的就是前面講述的哪種訪問方式,而我回答的是我的這種使用方式。正因為口頭描述,與實際回復真是差之千里。。。哈哈。為了驗證我朋友的這個,我特意寫了個這篇文章,希望對大家有所幫助。最后,謝謝大家花時間閱讀。
總結
以上是生活随笔為你收集整理的喜欢用Block的值得注意-Block的Retain Cycle的解决方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 看YYModel源码的一些收获
- 下一篇: iOS UIlabel文字排版(改变字间