引用類型在堆上的內存分配過程當中有 8 字節的地址長度用來保存對象的引用計數,堆上的內存並不像棧上那樣當即進行回收,系統會定時對堆上的內存進行檢查,當某個實例再也不被使用時,引用計數會變爲 0,此時系統會自動釋放實例所佔用的內存空間,一旦釋放就不能再訪問這個實例的屬性和方法。因爲該過程是自動的,不須要開發人員來開闢和釋放內存,所以稱爲自動引用計數,簡稱 ARC(Automatic Reference Counting)。swift
在構造器和析構器中分別寫一個打印語句,用來標示實例的建立和銷燬。性能
class Student { var name: String var age: Int init(name: String, age: Int) { self.name = name self.age = age print("建立了一個實例") } deinit { print("銷燬了一個實例") } }
聲明兩個變量,把它們的類型聲明爲 Student
的可選型,如今它們尚未被賦值。優化
var xiaoming: Student? var xiaogang: Student?
經過構造器建立一個 Student
的實例,而後把這個實例賦值給第一個變量。code
xiaoming = Student(name: "xiaoming", age: 12)
此時運行程序輸出以下。對象
建立了一個實例
此次讓第二個變量也引用這個實例,如今這個實例的引用計數爲 2,表明着 Student
實例的內存地址被引用了兩次。內存
xiaogang = xiaoming
下面經過給變量賦值 nil
來斷開引用,首先斷開一個變量的引用,如今 Student
實例的引用計數已變爲 1。開發
xiaogang = nil
接着斷開第二個變量的引用,如今沒有任何屬性或者變量引用這個實例了。it
xiaoming = nil
能夠看到中控臺打印信息以下,這個類調用了析構器,表明它被銷燬了,釋放出了實例所佔用的內存空間。class
銷燬了一個實例
看起來只是引用的數量增減那麼簡單,不過在真實的內存中,ARC 在檢驗某個對象的計數時不可避免的須要對堆內存進行加鎖和解鎖處理,也就是說不管你如何在代碼層面優化代碼,ARC 自己仍會帶來一部分性能的損耗,這也解釋了爲何值類型是更好的選擇。變量