2009-10-07 72 views
3

我只是寫一些探索性的代碼來鞏固我的Objective-C的理解和我碰到這個例子中,我沒有完全得到來了。我定義這個方法並運行代碼:代碼示例:爲什麼我仍然可以訪問這個對象NSString的我已經發布了它?

- (NSString *)stringMethod 
{ 
    NSString *stringPointer = [[NSString alloc] initWithFormat:@"string inside stringPointer"]; 
    [stringPointer release]; 
    [stringPointer release]; 
    NSLog(@"retain count of stringPointer is %i", [stringPointer retainCount]); 
    return stringPointer; 
} 

運行的代碼,調用此方法後,我注意到一些事情:

  1. 通常情況下,如果我嘗試訪問東西是後理應dealloced打零保留計數,我得到一個EXC_BAD_ACCESS錯誤。在這裏,我得到一個malloc「double free」錯誤。這是爲什麼?

  2. 無論我在代碼中添加多少行「[stringPointer release]」,NSLog都會報告保留計數爲1.當我添加更多版本時,我只會得到更多的「雙倍釋放」錯誤。爲什麼發佈聲明不按預期工作?

  3. 雖然我已經過度釋放stringPointer,但我收到了一堆「雙免費」錯誤,返回值仍然工作,如果沒有任何事情發生(我在主代碼中有另一個NSLog報告返回值)。該程序繼續正常運行。再次,有人可以解釋爲什麼發生這種情況?

這些例子是相當瑣碎,但我試圖讓這是怎麼回事十足的把握。謝謝!

+0

閱讀答案後,閱讀其他網站,並多玩一點,我開始認爲NSStrings不像其他對象那樣分開。例如,如果我使用UILabels而不是NSStrings執行相同的操作,那麼肯定會發生停止該程序的錯誤。在我看來,不管你是否「分配」一個NSString,在後臺它都被視爲一個基元而不是一個對象,而alloc/release語法就是爲了一致性。 – iPhoneToucher 2009-10-07 19:07:14

回答

6

你得到一個雙無錯,因爲你釋放兩次,使兩個的dealloc消息。 = P

請,只是因爲你釋放不併不意味着其在內存地址中的數據被立即銷燬頭腦。它只被標記爲未使用,所以內核知道在將來的某個時刻,它可以自由地用於另一部分數據。在此之前(在您的應用程序空間中完全不確定),數據將保留在那裏。

如此反覆:釋放(和dealloc'ing)在字節級不立即必要的數據銷燬。它只是內核的標記。

0

retainCount總是打印一個可能是由優化引起的 - 當發佈的通知將被釋放時,沒有理由將retainCount更新爲零(因爲此時沒有人應該引用該對象),而是更新retainCount只是解除分配它。

3

有兩件事情會在這裏的。首先,釋放對象並不一定會清除對象以前佔用的任何內存。它只是表示它是免費的。除非你做別的事情導致內存被重新使用,否則舊數據就會停滯不前。

在NSString的特定情況下,它是一個類集羣,這意味着您從alloc/init返回的實際類是NSString的某個具體子類,而不是NSString實例。對於「常量」字符串,這是一個非常輕量級的結構,只保留一個指向C字符串常量的指針。無論你製作多少張文件或多少次釋放它,都不會影響指向常量C字符串的指針的有效性。

嘗試在這種情況下檢查[stringPointer類],以及在可變字符串或實際使用格式字符和參數的格式化字符串的情況下。可能三個人都會有不同的班級。

相關問題