內存問題始終是軟件開發中的頭等大事,iOS開發中也不例外,在面試中也是必問的問題。今天咱們主要來說講Block中涉及的循環引用問題。當咱們本身一開始寫代碼的時候,可能會大量在block中使用self,可是當看到別人優秀的代碼的時候,發現別人經常不是用self,而使用weakSelf. 爲何呢?本文的示例代碼上傳至 https://github.com/chenyufeng1991/Block_WeakSelf 。 ios
首先我先來講說內存管理的原則:git
1.默認使用strong,可選weak。strong下無論成員變量仍是屬性,每次使用指針指向一個對象,就會自動調用retain,並對舊對象調用release,在須要釋放的時候設爲nil。github
2.避免循環引用,不然手動設置nil釋放。面試
3.建立block匿名函數以前通常須要對self進行weak化,不然形成循環引用沒法釋放controller。安全
首先Xcode爲咱們提供了良好的編譯環境,若是代碼中有可能出現循環引用的地方,Xcode會給咱們警告:「Capturing 'self' strongly in this block is likely to lead to a retain cycle」.如圖:app
。函數
block中的循環引用是這樣的:某個對象有一個copy或者strong成員變量或者屬性,這時block內部直接引用了成員變量或者self,這樣就產生了self持有block成員,block成員持有self,就會致使循環引用。由於self自己就是一個strong類型的變量。蘋果官方的建議是:傳進block以前,把self轉換成weak automatic的變量,這樣在block中就不會出現對self的強引用。若是在block執行完成以前,self被釋放,weakSelf也會置爲nil。weak類型相對比較安全,由於能夠在釋放後自動置爲nil,不會引發野指針。那麼如何來聲明呢?this
1.atom
[cpp] view plain copyspa
這句話的意思是聲明瞭一個self類型的weak指針,名字叫作weakSelf. typeof是用來求參數類型的,這裏也就是來求self的類型。這樣定義出的weakSelf就是和self是一個類型,而且是原self的一個弱引用。
2.
[cpp] view plain copy
3.
[cpp] view plain copy
下面我經過代碼演示一下:
(1)聲明幾個block和一個屬性:
[cpp] view plain copy
(2)使用weakSelf不會引發循環引用:
[cpp] view plain copy
(3)直接使用self,會循環引用:Xcode會給警告
[cpp] view plain copy
(4)要執行的方法抽取出來,也不會循環引用:
[cpp] view plain copy
[cpp] view plain copy
(5)block不是self的屬性或者變量時,在block內使用self也不會循環引用:
[cpp] view plain copy
(6)block的調用以下:
[cpp] view plain copy