2011-08-20 65 views
3

可能重複:
check retain count保留/釋放計數問題。需要澄清

,因爲我是用retainrelease計數玩,我遇到了一個情況,我不能夠解釋。請幫助我更好地理解它:

  • 有一類O。它不包含變量,什麼也不做。
  • 有一班Count。它初始化O和增量遞減計數它
  • 有2個按鈕的UI筆尖:保留和釋放

enter image description here

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
    o = [[O alloc]init]; // At this moment [o retainCount] is 1 as expected 
    .... 

每doRetain,如預期計算的增量

- (IBAction)doRetain:(id)sender { 
    [o retain]; 

    NSString *result = [[NSString alloc] initWithFormat:@"%d", [o retainCount]];  
    [label setText: result]; 
    [result release]; 

} 

每當釋放被調用,計數減少

- (IBAction)doRelease:(id)sender { 
    [o release]; 

    NSString *result = [[NSString alloc] initWithFormat:@"%d", [o retainCount]]; 
    [label setText: result]; 
    [result release]; 

} 

考慮1保留和2個版本

enter image description here

  1. 我們開始爲1的保留計數,分配初始化序列後
  2. ,再進行人工保留計數上升到2
  3. 然後,我們減少計數,它下降到1
  4. 之後whic h下一個減少.....看起來什麼都不做保持計數仍然是1
  5. 此版本引用壞內存並使應用程序崩潰。

請幫助我理解這種行爲

回答

4

如果保留計數爲1和鬆開,對象不再有效,而releaseCount財產是沒有意義的(且其結果是不可預知的)。

另外,我知道這是一個測試,但你用'alloc'創建你的字符串,但從不釋放它們。

使用發佈和保留時,您只負責釋放您自己的保留。其他物體可能會對有問題的物體執行保留,並且它們將依次釋放它們。

如果您使用包含單詞alloccopycreate的方法獲得對象,則表示該對象上有隱含的retain。否則,你可以假定在當前運行循環之後對象會消失,所以如果你想掛在對象的副本上,你需要執行一個保留。當你完成對象時,做一個發佈。

+0

這非常合理。感謝道格 – JAM

1

由於在最近的另一項訊息中提到你應該從來沒有真正使用[retainCount]功能!

check retain count

+0

那麼,那麼......你如何跟蹤你的保留數量? – JAM

+1

你不知道。您首先正確管理內存。 – jtbandes

+1

我同意你不應該將它們用於你的應用程序,但它們對於理解事物的工作方式非常有用。而@mac - 你永遠不會使用保留計數來決定是否釋放一個實例。我會詳細解釋我的答案。 –

2

其實,保留數是一個可怕的誤導性數據,是一個可怕的學習工具。您可以在保留計數計數是你所期望的值的唯一情況是如果:

  • 你繼承NSObject的(或創建自己的根類)

  • 不要你的對象傳遞給任何系統API 在所有

  • 不使用autorelease不斷

一旦您違反了這些規則的任何,保留計數就成爲其值超出了您的控制範圍的實現細節。當然,在簡單情況下,它會相對一致。直到它不是,然後你使用不準確的工具基於錯誤的假設來調試某些東西。

I.e.

請勿調用retainCount!

cocoa memory management guide準確定義應如何管理保留和釋放。

您應該將保留計數視爲增量;操作會使其保持不變或增加或減少操作。如果你讓它增加,你必須減少放棄所有權。絕對值不重要。