Swift 記憶體管理,迴圈引用

2022-05-06 07:42:08 字數 2259 閱讀 3780

在執行時點選

如果有記憶體洩漏的問題,在左側列表會出現如下

然後點選出問題的會出現如下圖,乙個contact類的物件和乙個number類的物件迴圈引用

allocation: 分配記憶體

initialization: 初始化

使用deinitialization:

deallocation: **記憶體

可以在init函式和deinit函式裡 print,init函式在分配完記憶體之後呼叫,deinit在**記憶體之前呼叫。

物件的有效範圍(未被**記憶體)

方案一: weak reference

關鍵字:weak

optional types,一定是變數var,不是let。 因為當引用計數變為0時會自動賦值為nil。

當引用計數變為0時,會呼叫class的deinit。

引用某個物件時不會增加物件的強引用計數。

方案二:unowned reference

關鍵字:unowned

應用場景: objecta 擁有 objectb, objectb 需要宣告被objecta擁有,但是不能在class 裡直接宣告 let owner: classa(等價於 objectb 擁有owner這個屬性,導致強引用), 所以加關鍵字 unowned

不會導致強引用計數增加。

unowned只能使用在reference types (例如:class), 不能使用在value types (例如:struct,array)。

對比圖:

方案三:capture list - 解決閉包引用迴圈

例子:

var x = 5

var y = 5

let someclosure =

x = 6

y = 6

someclosure()

//output: 5,6

執行someclosure時capture list 捕獲了此時x的值,之後x的值改變並不會影響someclosure,因為someclosure使用的是x的值,但是使用的是y的引用,所以在呼叫someclosure()時,y的指標指向的值是6而不是5。

問題一:

在乙個類中宣告乙個改類的閉包屬性,此閉包內有呼叫了改類的其他屬性就導致了改類的迴圈引用。舉例:

///

------------ error ------------

///class

greeting

lazy var greetingmaker: () -> string =

}

如果這樣去解決問題

//

mermaid的作用域只在do{}裡

//在do{}之後呼叫mermaid.greetingmaker 會觸發runtime exception

是合法的,但是mermaid在do{}之外時已經被**記憶體了

class

greeting

lazy var greetingmaker: () -> string =

}let greetingmaker: () ->string

dogreetingmaker()

會出現runtime exception

更好的解決方案:

///

------------ fix error ------------

///class

greeting

lazy var greetingmaker: () -> string =

return

"hello \(strongself.who)."}

}let greetingmaker: () ->string

dogreetingmaker()

更詳細的blog請移步:

Swift 迴圈引用

要解決閉包引起的迴圈引用,swift 中引入了 捕獲列表 的概念,在閉包的引數列表中將閉包體中涉及的所有被 持有 物件宣告為 無主引用 或者 弱引用 以逗號隔開。將閉包作為類的屬性是一種非常常見的做法,相比於定義乙個方法,定義乙個閉包型別的屬性可以隨時修改閉包中的執行內容,以此達到復用的效果,減少乙...

OC 記憶體管理 迴圈引用

儲存消耗空間 ram rom 記憶體模型 cg arc mrc 記憶體變數 堆 棧 靜態區 迴圈引用在block函式中經常發生舉個例子 建立兩個全域性變數 乙個為block 另乙個是str inte cenextviewcontroller property nonatomic,strong dis...

Swift 排查引用迴圈

恢復內容開始 一 最近使用rxswift在多次訊號的巢狀中,發現乙個物件始終始終無法釋放 開始想通過memory graph驗證是否沒有釋放,一直報錯,後來確認是xcode的bug 始終無法確認問題,只能考慮使用乙個弱引用的陣列來驗證了 final class weakbox 類定義 private...