Swift ARC 自動引用計數

一、ARC

  • 引用類型在堆上的內存分配過程當中有 8 字節的地址長度用來保存對象的引用計數,堆上的內存並不像棧上那樣當即進行回收,系統會定時對堆上的內存進行檢查,當某個實例再也不被使用時,引用計數會變爲 0,此時系統會自動釋放實例所佔用的內存空間,一旦釋放就不能再訪問這個實例的屬性和方法。因爲該過程是自動的,不須要開發人員來開闢和釋放內存,所以稱爲自動引用計數,簡稱 ARC(Automatic Reference Counting)。swift

    • 爲了不使用中的實例被釋放,ARC 會跟蹤並計算每個實例被多少屬性、常量和變量所引用。
    • 引用有強引用和弱引用之分,這是爲了保證在某些循環引用的狀況下能夠打破循環。
    • 爲了保證明例在被屬性、常量和變量引用時不會被意外釋放,引用默認狀況下會被設定爲強引用。

1.1 ARC 示例

  • 在構造器和析構器中分別寫一個打印語句,用來標示實例的建立和銷燬。性能

    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 自己仍會帶來一部分性能的損耗,這也解釋了爲何值類型是更好的選擇。變量

相關文章
相關標籤/搜索