Reference Count/Retain/Release

Objective-C 語言裡頭每個物件,都是指向某塊記憶體的指標,在 C語言當中,你會使用像是 malloccalloc 這些 function配置記憶體,用完之後,就呼叫 free釋放記憶體。但是我們如何知道一塊記憶體被多少地方用到,之後這些地方又不再用到呢?所以在Objective-C語言發展之初,就建立了一套計算有多少地方用到某個物件的簡單機制,叫做reference count,意義非常簡單:只要一個物件被某個地方用到一次,這個地方就對這個物件加一,反之就減一,如果數字減到變成了零,就該釋放這塊記憶體。

一個物件如果使用 allocinit …產生,初始的 reference count 為 1。接著,我們可以使用 retain 增加 reference count。

[anObject retain]; // 加 1

反之就用 release

[anObject release]; // 減 1

我們可以使用 retainCount 檢查某個物件被 retain 了多少次。

NSLog(@"Retain count: %d", [anObject retainCount]);

有了基本概念之後,我們就可以看出以下程式有什麼問題

id a = [[NSObject alloc] init];
[a release];
[a release];

因為在第二行,a所指向的記憶體已經被釋放了,所以第三行想要再釋放一次,就會造成錯誤。同樣的:

id a = [[NSObject alloc] init];
id b = [[NSObject alloc] init];
b = a;
[a release];
[b release];

在第三行中,由於 b 指向了 a 原本所指向的記憶體,但是 b原本所指向的記憶體卻沒有釋放,同時再也沒有任何變數指向 b原本指向的記憶體,因此這塊記憶體就發生了記憶體漏水。接著,在第四行呼叫[a release] 時,這塊記憶體就已經被放掉了,但是由於 a 與 b都已經指向了同一塊記憶體,所以第五行的 [b release]也是操作同一塊記憶體,於是會發生 EXC_BAD_ACCESS 錯誤。

results matching ""

    No results matching ""