[iOS] Memory Management

變數與常數的生命週期

(1.) Function

Function的參數, 區塊{ }內的變數與常數會隨著執行任務的結束而釋放記憶體空間

func test(text: String) {
    var value1: Int = 1
    let value2: Int = 2
}

test("haha")
//此時釋放 text, value1, value2 記憶體

(2.) Structure

Structure區塊{ }內的變數與常數會隨著Structure變數不再被參考到而釋放記憶體空間

struct Test {
    var value1: Int = 1
    let value2: Int = 2
}

var test: Test? = Test()
test = nil   //此時釋放 value1, value2 記憶體

(3.) Class

同樣的, Class區塊{ }內的變數與常數會隨著Class變數不再被參考到而釋放記憶體空間

類別解構函式deinit

deinit{} 會在Class release前被呼叫, 我們可以利用這個function觀察Class是否有被釋放或執行一些動作

Reference Cycle

Swift是遵循著自動引用計數 (ARC) 的規則, 通常當一個物件沒有被其他對象引用時會自動被銷毀, 但有些情況下物件會互相參考, 行成Reference Cycle, 造成物件的記憶體永遠不會被釋放.

(1.) 經典例子: Closure

Reference Cycle: self擁有了onComplete, onComplete也擁有self

Solution:

若是在release Test 物件之前, 先release onComplete, 則可以正常釋放物件

但有更好的做法, 使用unownedweak關鍵字

(2.)經典例子: Apple官方例子

Solution:

A = nil 之後 把B?.lover也設成nil, 則可以正常釋放記憶體

但有更好的做法, 使用weak關鍵字

unowned 與 weak

(1.) unowned用於非optional的變數

unowned 通常都用於該物件不會比或持有它的物件更早被release,

[unowned self]可以看做self!

(2.) weak用於optional的變數

如遇到網路request, user在 response回來之前就返回上一頁, 使的物件有可能會比或持有它的物件更早被release, 則必須使用weak, [weak self]可以看做self?

(若使用unowned 此時會造成crash)

Last updated