前言
llvm編譯器的好:swift的記憶體管理除了要注意引用迴圈之外,幾乎全部被llvm編譯器包攬,不需要開發人員操心。
swift 是自動管理記憶體的,這也就是說,我們不再需要操心記憶體的申請和分配。當我們通過初始化建立乙個物件時,swift 會替我們管理和分配記憶體。而釋放的原則遵循了自動引用計數 (arc) 的規則:當乙個物件沒有引用的時候,其記憶體將會被自動**。這套機制從很大程度上簡化了我們的編碼,我們只需要保證在合適的時候將引用置空 (比如超過作用域,或者手動設為 nil 等),就可以確保記憶體使用不出現問題。
但是,所有的自動引用計數機制都有乙個從理論上無法繞過的限制,那就是迴圈引用 (retain cycle) 的情況。
引用迴圈問題是什麼
swift 使用 arc(自動引用計數)的方法為引用型別管理記憶體。
在 swift 中,當宣告引用型別的變數並將物件負值給他時,相當於建立了對該物件的強引用,該物件的引用計數將加1。如果兩個物件相互強引用,將導致引用迴圈。引用迴圈一旦出現,相關的物件將無法釋放,從而產生記憶體洩漏。
引用迴圈問題出現的場景與解決辦法
swift中類物件和閉包都是通過引用進行傳值,所以以下場景會出現引用迴圈:
程式設計客棧類物件相互強引用
兩個物件彼此引用對方時,形成引用迴圈。
class letter
deinit
}class mailbox
deinit
}letter 類中強引用了 mailbox 類物件,mailbox 類中又強引用了 letter 類物件形成引用迴圈。
解決辦法:宣告物件時加入 weak 關鍵字(弱引用)可以解除強引用。比如將 letter 物件宣告為 weak 時,mailbox 物件的引用計數不會加1,從而解除引用迴圈。一般將邏輯上屬於另一物件的物件宣告為弱物件。如:
weak var letter : letter?
閉包中引用包含自身的物件
閉包中引用包含自身的物件也會造成引用迴圈。
class mailchecker
init(name: string)
deinit
}示例**中 whosemail 的閉包中使用 self 引用了包含自身的 mailchecker 物件,此時該閉包擁有 mailchecker 物件,而 mailchecker 物件又擁有該閉包,導致引用迴圈。
解決辦法:此時可以新增[unowned self]讓 swift 知道不應保留 self 物件,從而解除引用迴圈。將閉包改為:
lazy var whosemail: () -> string =
注:**均取自 boisy g. pitre《swift基礎教程》
總結本文標題: 深入講解swift的記憶體管理
本文位址: /ruanjian/swift/181863.html
Swift記憶體管理 示例講解
具體而言,swift中的arc記憶體管理是對引用型別的管理,即對類所建立的物件採用arc管理。而對於值型別,如整型 浮點型 布林型 字串 元組 集合 列舉和結構體等,是由處理器自動管理的,程式設計師不需要管理它們的記憶體。一 引用計數 每個swift類建立的物件都有乙個內部計數器,這個計數器跟蹤物件...
swift 記憶體管理
不管在什麼語言裡,記憶體管理的內容都很重要,所以我打算花上比其他 tip 長一些的篇幅仔細地說說這塊內容。swift 是自動管理記憶體的,這也就是說,我們不再需要操心記憶體的申請和分配。當我們通過初始化建立乙個物件時,swift 會替我們管理和分配記憶體。而釋放的原則遵循了自動引用計數 arc 的規...
Swift 記憶體管理
1 object c 經歷兩個階段 1 手動引用計數記憶體管理 manual reference counting,mrc 2 自動引用計數記憶體管理 automatic refernce counting,arc 2 引用型別 記憶體分配到 堆 上,需要人為管理。值型別 記憶體分配到 棧 上,有處...