ios-常見的循環引用

介紹:

循環引用,指的是多個對象相互引用時,使得引用造成一個環形,致使外部沒法真正是否掉這塊環形內存。其實有點相似死鎖。ios

舉個例子:A->B->C->....->X->B   ->表示強引用,這樣的B的引用計數就是2,假如A被系統釋放了,理論上A會自動減少A所引用的資源,就是B,那麼這時候B的引用計數就變成了1,全部B沒法被釋放,然而A已經被釋放了,全部B的內存部分就確定沒法再釋放再從新利用這部份內存空間了,致使內存泄漏。xcode

狀況一:delegate

Delegate是ios中開發中最常遇到的循環引用,通常在聲明delegate的時候都要使用弱引用weak或者assign安全

@property (nonatomic, weak, nullable) id <UITableViewDelegate> delegate;

固然怎麼選擇使用assign仍是weak,MRC的話只能用assign,在ARC的狀況下最好使用weak,由於weak修飾的變量在是否後自動爲指向nil,防止不安全的野指針存在函數

狀況二:Block

Block也是比較常見的循環引用問題,在Block中使用了self容易出現循環引用,所以不少人在使用block的時候,加入裏面有用到self的操做都會聲明一個__weak來修飾self。其實便不是這樣的,不是全部使用了Block都會出現Self循環引用問題,只有self擁有Block的強引用纔會出現這種狀況。atom

因此通常在函數中臨時使用Block是不會出現循環應用的,由於這時候Block引用是屬於棧的。當棧上的block釋放後,block中對self的引用計數也會減掉spa

固然不必定要Self對Block有直接的引用纔會出現,假如self的變量B,B中有個Block變量,就容易出現這種狀況,好的是在block出現循環引用的,xcode7會出現警告提示(以前版本不肯定)。指針

狀況三:NSTimer

這是一個神奇的NSTimer,當你建立使用NSTimer的時候,NSTimer會默認對當前self有個強引用,全部在self使用完成打算是否的時候,必定要先使用NSTimer的invalidate來中止是否時間控制對self的引用code

[_timer invalidate];

 

----------------------------------凌亂的分割線-------------------------------------對象

上面說的是咱們常見的,其實循環引用就是說咱們的強引用造成了閉環,還會有不少本身寫的代碼中會出現,平時仍是要注意寫法。固然xcode的instruments也能幫助到你們排除一些這樣相似的內存問題。內存

相關文章
相關標籤/搜索