ios 中的迴圈引用問題及解決

2022-05-10 13:28:38 字數 1251 閱讀 6923

迴圈引用,指的是多個物件相互引用時,使得引用形成乙個環形,導致外部無法真正是否掉這塊環形記憶體。其實有點類似死鎖。

舉個例子:a->b->c->....->x->b   ->表示強引用,這樣的b的引用計數就是2,假如a被系統釋放了,理論上a會自動減小a所引用的資源,就是b,那麼這時候b的引用計數就變成了1,所有b無法被釋放,然而a已經被釋放了,所有b的記憶體部分就肯定無法再釋放再重新利用這部分記憶體空間了,導致記憶體洩漏。

情況一:delegate

delegate是ios中開發中最常遇到的迴圈引用,一般在宣告delegate的時候都要使用弱引用weak或者assign

@property (nonatomic, weak, nullable) id  delegate;

當然怎麼選擇使用assign還是weak,mrc的話只能用assign,在arc的情況下最好使用weak,因為weak修飾的變數在是否後自動為指向nil,防止不安全的野指標存在

情況二:block

block也是比較常見的迴圈引用問題,在block中使用了self容易出現迴圈引用,因此很多人在使用block的時候,加入裡面有用到self的操作都會宣告乙個__weak來修飾self。其實便不是這樣的,不是所有使用了block都會出現self迴圈引用問題,只有self擁有block的強引用才會出現這種情況。

所以一般在函式中臨時使用block是不會出現迴圈應用的,因為這時候block引用是屬於棧的。當棧上的block釋放後,block中對self的引用計數也會減掉

當然不一定要self對block有直接的引用才會出現,假如self的變數b,b中有個block變數,就容易出現這種情況,好的是在block出現迴圈引用的,xcode7會出現警告提示(之前版本不確定)。

情況三:nstimer

這是乙個神奇的nstimer,當你建立使用nstimer的時候,nstimer會預設對當前self有個強引用,所有在self使用完成打算是否的時候,一定要先使用nstimer的invalidate來停止是否時間控制對self的引用

[_timer invalidate];

----------------------------------凌亂的分割線-------------------------------------

上面說的是我們常見的,其實迴圈引用就是說我們的強引用形成了閉環,還會有很多自己寫的**中會出現,平時還是要注意寫法。當然xcode的instruments也能幫助到大家排除一些這樣類似的記憶體問題。

iOS開發中的迴圈引用問題

nstimer經常會被作為類的成員變數,而nstimer初始化時要指定self為target,造成迴圈引用。另一方面,若timer一直處於validate的狀態,則其引用計數將始終大於0。先看一段nstimer使用的例子 arc模式 解決方案 自定義類 wsweaktimertarget h檔案 i...

iOS迴圈引用問題

今天面試問道了迴圈引用,所以就看了看,原來只是知道使用了block容易造成迴圈引用。今天就來簡單的介紹一些迴圈引用。先來簡單介紹一下什麼是迴圈引用?迴圈引用可以簡單的理解成 a物件引用了b物件,b物件又引用了a物件。兩者相互保持對方的乙個引用。導致任何時候計數都不為0,最終兩者都無法釋放。產生迴圈引...

iOS之迴圈引用問題

記憶體中和變數有關的分割槽 堆 棧 靜態區。其中,棧和靜態區是作業系統自己管理的,對程式設計師來說相對透明,所以,一般我們只需要關注堆的記憶體分配,而迴圈引用的產生,也和其息息相關,即迴圈引用會導致堆裡的記憶體無法正常 從而導致記憶體洩漏。1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值...