2011-08-16 48 views
1

在我閱讀過的大多數教程中都有自定義init方法的示例。發佈可能尚未創建的對象

例如

@implementation MyPerson 

-(id) initWithDefaultName { 
self = [super init]; 
if (self) { 
NSString *name = [[NSString alloc] initWithString:@"John Doe"]; 
} 
return self; 
} 

現在,我知道,我應該與

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

配對這件事我不明白不過,就是這也不會,如果我崩潰打電話[MyPerson init]其次[MyPerson release]

編輯:讀下面的評論,我意識到上面的示例代碼是不完全正確的。我得到的是我的自定義initWithName方法分配並初始化一個對象,如果標準的init方法被調用將不會存在。因此,我的dealloc方法包含釋放它的代碼,但即使名稱對象從未創建過,它仍然有效?

+0

關於該編輯:'name'會** **不能在被釋放'dealloc'因爲你分配給一個局部變量,而不是'name'實例變量。 init方法中的這個語句應該只讀取'name = [[NSString alloc] initWithString:@「John Doe」];'以獲得您想要的效果。 – PeyloW

回答

2

在Java中,如果你這樣做:

Foo foo = null; 
int bar foo.getBar(); 

你會得到一個空指針異常。在Objective-C中,發送消息到nil是完全可以的,它被視爲無操作,沒有任何操作。

有一個小警告;返回類型大小適合ABI默認返回約定的方法將產生一個返回值,其值等於nil的數據類型表示形式。因此,這將所有的工作和產量預期的返回值:

Foo* foo = nil; 
id a = [foo objectValue]; // a will be nil 
BOOL b = [foo boolValue]; // b will be NO 
int c = [foo intValue];  // c will be 0 
float d = [foo floatValue]; // d will be 0.0f 

這可以有很大的好處到你的代碼,想像這個例子:

if ([myString length] > 0) { 
    // Do stuff here 
} 

這樣,如果myString是空的也沒關係字符串,或者只是nil。在這兩種情況下,詢問長度將返回0。由於nil的價值很少需要考慮,所以使得許多​​操作更容易編寫。

僅適用於返回類型,比如結構,不適合在返回寄存器,你是不會得到一個定義的返回值:

Foo* foo = nil; 
CGRect a = [foo rectValue]; // content of a will be undefined. 
+0

夢幻般的答案。這應該是公認的,不是我的! – jrturton

+0

這是否仍然如此,考慮到我對上述問題所做的修改? –

+0

@Jack:沒有,你的範圍內有邏輯錯誤,我寫了一個關於這個話題的問題的評論。 – PeyloW

1

您可以安全地將發佈發​​送到零。請注意,儘管如此,當您將它分配給init時應該保留名稱。

+1

名稱是字符串文字,在這裏。你也可以保留它們,但它並不是真的有必要(保留簡直沒有效果,也沒有釋放,AFAIK)。儘管名稱不是文字,但它必須保留。 –

+0

我不知道,謝謝你 – jrturton

+0

對不起,我只是重新閱讀代碼,並意識到這不是我正在得到的。我修改了它。 –

5

實例變量的默認值爲nil。發送消息到nil不起作用。

1

你可以發送任何東西到nil對象,它會很好。

這就是爲什麼大多數教程還將其每個屬性的viewDidUnload方法設置回nil的原因。