生存週期:自動引用計數

前邊鋪墊了那麼多,現在終於要講到垃圾回收這個東西了。

這不是方舟……這是自動引用計數(Automatic Reference Counting),這個東西是蘋果用來管理內存的。

它的功能就是那個垃圾堆上的垃圾回收器。它能夠保證所有在堆上運行的對像被釋放後不會一直駐留在堆上。保證了那塊內存會再分配給其他要使用的對像上。

何為釋放

說到對象會不會被垃圾回收器給收走,那就要看引用會不會釋放了:我們這樣來分辨一個對像是否還在被使用——當沒有引用再指向某個對象的時候,我們就說它已經被釋放了——因為它再也不會被訪問到了。

釋放的方法

我們一般有三種方法可以釋放掉對一個對象的引用:

  • 把引用放在方法裡,方法出棧,引用完蛋——對像沒了引用,會被回收。
  • 引用更改指向到其他對像上——原本的對像沒有了引用,會被回收。
  • 直接清空引用——前提是你聲明的儲存器是可選類型。

好了,現在我們分別來舉幾個栗子看:

方法執行完畢出棧,臨時變量沒了——對象自然就釋放掉了。arc 發現對像沒有引用了,那麼這個對象就會被收回,留下的空間給別人用。

我們吧 gun2 的引用賦給 gun1,那麼 gun1原來的引用就被覆蓋掉了,那對應的對像也就只能等著被回收啦!

我們重新給 gun1 賦值為空,那麼引用沒了,對像也就隨之完蛋了。

交叉引用

有這麼一種情況,會導致自動引用計數捉雞,我們來看看:

我們稍微修改了剛才的類,增加了一個 Aaa 類的引用屬性,然後創建了這個 Aaa 的類,這個類包含了一個 Gun 類的引用屬性,這時候我們把它兩個互相引用,然後再釋放掉……等等,真的可以釋放掉嗎?

然而並不能。

我們回顧一下一個對像被釋放的定義:當對像沒有引用就稱作被釋放——可是這兩個對像都還有互相之間的引用呢!

所以,我們雖然訪問不到這兩個對象了,但是它們兩個互相還引用著,arc 無計可施,你一樣也不能再訪問到它們——這就叫著名的“內存洩露”。

弱引用

這時候,我們要打破這個環路,讓引用能夠斷開,這樣才能讓這個互相引用的對像一個一個地被釋放掉。我們需要將其中一個聲明為弱引用,只有這樣才能讓 arc 斷開他們之間的環路。

這樣就好了,環路會被打斷,洩露的內存也被找回來了。

弱引用的要求

  • 弱引用必須是變量,不能是常量,因為它得可以被修改。
  • 弱引用必須是可選項,它得能被清空。

 

 

由...出版 R0uter

如非聲明,本人所著文章均為原創手打,轉載請註明本頁面鏈接和我的名字。

加入對話

1 評論

您的電子郵件地址不會被公開. 必填字段標 *