在執行時點選
如果有記憶體洩漏的問題,在左側列表會出現如下
然後點選出問題的會出現如下圖,乙個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執行someclosure時capture list 捕獲了此時x的值,之後x的值改變並不會影響someclosure,因為someclosure使用的是x的值,但是使用的是y的引用,所以在呼叫someclosure()時,y的指標指向的值是6而不是5。var y = 5
let someclosure =
x = 6
y = 6
someclosure()
//output: 5,6
問題一:
在乙個類中宣告乙個改類的閉包屬性,此閉包內有呼叫了改類的其他屬性就導致了改類的迴圈引用。舉例:
///如果這樣去解決問題------------ error ------------
///class
greeting
lazy var greetingmaker: () -> string =
}
//會出現runtime exceptionmermaid的作用域只在do{}裡
//在do{}之後呼叫mermaid.greetingmaker 會觸發runtime exception
是合法的,但是mermaid在do{}之外時已經被**記憶體了
class
greeting
lazy var greetingmaker: () -> string =
}let greetingmaker: () ->string
dogreetingmaker()
更好的解決方案:
///更詳細的blog請移步:------------ fix error ------------
///class
greeting
lazy var greetingmaker: () -> string =
return
"hello \(strongself.who)."}
}let greetingmaker: () ->string
dogreetingmaker()
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...