閱讀134 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Swift內存管理-示例講解

具體而言,Swift中的ARC內存管理是對引用類型的管理,即對類所創建的對象采用ARC管理。而對於值類型,如整型、浮點型、布爾型、字符串、元組、集合、枚舉和結構體等,是由處理器自動管理的,程序員不需要管理它們的內存。
一、引用計數
每個Swift類創建的對象都有一個內部計數器,這個計數器跟蹤對象的引用次數,稱為引用計數(Reference Count,簡稱RC)。當對象被創建的時候,引用計數為1,每次對象被引用的時候會使其引用計數加1,如果不需要的時候,對象引用斷開(賦值為nil),其引用計數減1。當對象的引用計數為0的時候,對象的內存才被釋放。
下圖是內存引用計數原理示意圖。圖中的房間就好比是對象的內存,一個人進入房間打開燈,就是創建一個對象,這時候對象的引用計數是1。有人進入房間,引用計數加1;有人離開房間,引用計數減1。最後一個人離開房間,引用計數為0,房間燈關閉,對象內存才被釋放。

二、示例:Swift自動引用計數
下麵我們通過一個示例了解一下Swift中的自動引用計數原理。下圖是Employee類創建的對象的生命周期,該圖描述了對象被賦值給3個變量,以及它們的釋放過程。

示例代碼如下:
class Employee {				①
var no : Int
var name : String
var job : String
var salary : Double


init(no : Int, name: String, job : String, salary : Double) {	②
    self.no = no
    self.name = name
self.job = job
self.salary = salary
println("員工\(name) 已經構造成功。")	③
    }
deinit {							④
println("員工\(name) 已經析構成功。")	⑤
    }    
}


var ref1: Employee?			⑥
var ref2: Employee?			⑦
var ref3: Employee?			⑧


ref1 = Employee(no: 7698, name: "Blake", job :"Salesman", salary : 1600)	⑨


ref2 = ref1						⑩
ref3 = ref1						⑪


ref1 = nil						⑫
ref2 = nil						⑬
ref3 = nil						⑭


上述代碼第①行聲明了Employee類,第②行代碼是定義構造器,在構造器中初始化存儲屬性,並且在代碼第③行輸出構造成功信息。第④行代碼是定義析構器,並在代碼第⑤行輸出析構成功信息。

代碼第⑥~⑧行是聲明3個Employee類型變量,這個時候還沒有創建Employee對象分配內存空間。代碼第⑨行是真正創建Employee對象分配內存空間,並把對象的引用分配給ref1變量,ref1與對象建立“強引用”關係,“強引用”關係能夠保證對象在內存中不被釋放,這時候它的引用計數是1。第⑩行代碼ref2 = ref1是將對象的引用分配給ref2,ref2也與對象建立“強引用”關係,這時候它的引用計數是2。第⑪行代碼ref3 = ref1是將對象的引用分配給ref3,ref3也與對象建立“強引用”關係,這時候它的引用計數是3。
然後在代碼第⑫行通過ref1 = nil語句斷開ref1對Employee對象的引用,這時候它的引用計數是2。以此類推,ref2 = nil時它的引用計數是1,ref3 = nil時它的引用計數是0,當引用計數為0的時候Employee對象被釋放。
我們可以測試一下看看效果,如果設置斷點單步調試,會發現代碼運行完第⑨行後控製台輸出:
員工Blake 已經構造成功。
析構器輸出的內容直到運行完第⑭行代碼才輸出:
員工Blake 已經析構成功。

這說明隻有在引用計數為0的情況下才調用析構器,釋放對象。


更多內容請關注國內第一本Swift圖書《Swift開發指南》
本書交流討論網站:https://www.51work6.com/swift.php
歡迎加入Swift技術討論群:362298485

歡迎關注智捷iOS課堂微信公共平台


最後更新:2017-04-03 05:40:12

  上一篇:go Java4android學習之對象導論
  下一篇:go poj 2656 Unhappy Jinjin