2011-04-15 80 views
1

類定義:爲什麼在釋放對象時仍然可以調用Objective C方法?

#import "MyClass.h" 


@implementation MyClass 

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     // Initialization code here. 
    } 

    return self; 
} 

- (void)dealloc 
{ 
    [super dealloc]; 
} 

- (void)print 
{ 
    NSLog(@"Hello World"); 

} 

@end 

及主要文件:

MyClass * m = [[MyClass alloc]init]; 
[m print]; 

[m release]; 

[m print]; 

結果:

的Hello World

的Hello World

當對象是爲什麼第二個方法仍然調用釋放?

回答

3

釋放一個對象只會標記它被用作可用於其他用途的內存。它不會用零或者類似的東西覆蓋它。在你的例子中,你沒有創建任何新的對象,所以沒有機會重用以前稱爲「m」的內存。

這爲什麼它是一個常見的模式,以釋放對象分配零指針,以防止意外再次使用無效目標:

[m release] 
m = nil; 
+0

我可能會評論這種有爭議的模式。通過將變量設置爲零,您的應用程序在發佈後使​​用時不會崩潰,這很好,但它可能會更難追蹤內存管理中的錯誤,因爲它不會崩潰,所以您可能不知道自己有問題。由於這些問題,我個人不會使用這種模式。 – GorillaPatch 2011-04-15 07:07:52

+0

我虔誠地使用存取方法,所以我可以依靠一方面的手指來了解我在過去十年中存在的內存管理錯誤的數量 - 而且這些錯誤很容易追蹤,因爲相關代碼總是很好封裝在setter方法中。 :-) – 2011-04-15 07:11:17

+0

你是對的,有很少的例子不依賴accessor方法。但如果你這樣做,那麼設置爲零也是沒有必要的。我在內存管理方面也沒什麼問題。不過,對於初學者來說,我個人認爲,如果出現問題,應用程序會崩潰而不是默默地失敗。但是,將變量設置爲nil並使用'NSZombiesEnabled'似乎也是一個不錯的選擇。 – GorillaPatch 2011-04-15 07:16:02

1

這是因爲該對象的記憶仍然是到位,並沒有被垃圾覆蓋。此外,所討論的方法不依賴於任何其他(已發佈)的實例變量。簡而言之:這只是純粹的機會。

嘗試設置環境變量NSZombieEnabled並再次運行,看看你真的只是「運氣」。

0

訪問釋放的內存是未定義的行爲。當你調用未定義的行爲時,會發生任何事情。這屬於「任何事情」的標題,所以發生這種事情是合理的 - 即訪問錯誤的對象或者崩潰,這也是可能的結果。

+0

它基本上是俄羅斯輪盤賭;-) – GorillaPatch 2011-04-15 07:57:08

相關問題