昨天在解釋資料類型的時候有提到 ARC 和一些東西,今天就來解釋一下這些東西吧
ARC,全名 Auto Reference Counting,是 Swift 特別用來觀察 reference type 資料的東西,它會自動的去計算現在有多少連結是指向某個 reference type 資料,而當沒有任何連結指向的時候,它會去釋放 reference type 資料的記憶體。
來實際看一下,以昨天的 reference type 為例,首先要在 class 裡設定它的 deinit,也就是當這個資料被釋放前要做的事,然後我們執行一次可以看到,deinit 沒有被觸發,這是因為 referenceType 這個變數依然還存有一個連結指向 test 這個 class。
那接下來我們將 referenceType 這個變數設成 nil 可以看到,現在沒有連結指向 test 了,所以 deinit 被觸發了,這個 class 就被釋放了,這就是 ARC 主要在做的事情:觀察 reference type 的資料連結數量,當連結等於 0 的時候就會自動釋放記憶體。
那介紹完 ARC 之後,來解釋一下使用 reference type 時可能會遇到的問題:Retain Cycle。
那這裡一樣,先在 class 裡新增變數,他的類型是 test,然後建立兩個都是 test 類型的變數,再把它們設為 nil,可以看到,它們按照順序被釋放了。
那現在,將 referenceType2 的 retain 設為 referenceType,再把兩個變數設為 nil,可以看到,它們被釋放了的順序顛倒了。
這是因為雖然將 referenceType 設為 nil 了,但是 referenceType2 還存有一個連結指向 referenceType,然後當 referenceType2 被設為 nil 的時候,referenceType2 先被釋放,之後沒有連結指向 referenceType 的時候,referenceType 才會被釋放。
那如果我將 referenceType 的 retain 設為 referenceType2,再把兩個變數設為 nil 呢?
可以看到,誰都沒有被釋放,這是因為雖然它們被設為 nil 了,但它們依舊存有一個連結指向彼此,形成一個循環,也就是 Retain Cycle。
這會導致兩個變數都不能被釋放,同時也無法對它們做任何事,這種情況就叫做 Memory Leak,失去對某一塊記憶體使用和管理的能力。
那關於 ARC 和 Retain Cycle 的部分就先到這裡,明天來說一下要怎麼處理 Retain Cycle。