2011-05-12 37 views
3

我已經開始學習Three20,我有一個簡單的問題,關於TT_RELEASE_SAFELY 到現在爲止我喜歡寫這樣的代碼:設置對象發行後零 - TT_RELEASE_SAFELY

UILabel *lab = [[UILabel alloc] initWithFrame:rect]; 
[self.view addSubview:lab]; 
[lab release]; 

在這裏,我想主池負責釋放lab的內存。

現在我已經找到TT_RELEASE_SAFELY這就好比是這樣定義的:

#define TT_RELEASE_SAFELY(__POINTER) { [__POINTER release]; __POINTER = nil; } 

正如你所看到的,發佈後,它會將對象nil

我想知道兩種方式之間的區別以及哪種方式更好。

謝謝。

回答

6

Sending a message to nil在Objective-C中有效。將消息發送到釋放對象不是。

發送消息到解除分配的對象:

id obj = [[MyClass alloc] init]; 
[obj release]; 
[obj doSomething]; // Crash!

發送消息到零:

id obj = [[MyClass alloc] init]; 
[obj release], obj = nil; 
[obj doSomething]; // Valid

對象之後分配爲零到可變已釋放是有爭議的,因爲它可以防止你意識到某些事情是錯誤的。 Sedate Alien的例子:

[controlCenter dealloc]; 
... 
float timeLeft = [controlCenter timeToWaitBeforeBombDetonation]; 

由於controlCenter已被釋放,此代碼將崩潰。因此,這種缺陷將被及早發現並修復。

[controlCenter dealloc], controlCenter = nil; 
... 
float timeLeft = [controlCenter timeToWaitBeforeBombDetonation]; 

該代碼會將0.0賦值給timeLeft,即使controlCenter爲零,該值也是有效的等待時間。


就拿上面一粒鹽,因爲如果你正在寫一個Objective-C的應用程序,你可能更關心的是保持你的用戶通過避免崩潰不是破壞城市幸福。如果後者是一個問題,你應該使用像Ada這樣的類型安全的語言。

+0

我這麼認爲,這是一種最佳實踐! – scorpiozj 2011-05-12 03:02:52

+0

通過「有效」,我假設你的意思是「不會在這個特定點上崩潰」。它不會「做些什麼」(正如名字所暗示的),也許它應該是'[obj wontDoAnything];'而不是? – 2011-05-12 03:04:51

+0

@Sedate Alien:它不會在沒有被調用的方法上做任何事情,但如果你選擇使用它,它會給你一個有效的返回值(0,NO等)。 – titaniumdecoy 2011-05-12 03:08:26

0

唯一的區別是,TT_RELEASE_SAFELY在釋放後將指針設置爲零,因此引用在發佈後不會使用。這個模式是一個很好的模式,TT_RELEASE_SAFELY宏使它更易於實現。

+0

也謝謝! – scorpiozj 2011-05-12 03:03:15

1

我相信使用這些「安全版本」的變體是明確不好的想法。

您的應用程序將以無聲和神祕的方式失敗,因爲傳遞給nil的消息不會引發任何警告。最好不要將你的參考文獻刪去,並利用NSZombieEnabled所提供的全部優勢。

+2

或....'#define TT_RELEASE_UNSAFELY(__ POINTER){[__POINTER release]; __POINTER =(id)0x42; }' – bbum 2011-05-12 02:48:54

+0

@bbum:也可以。 :) – 2011-05-12 03:02:19

+0

我想我們可以在使用它之前檢查一個對象是否等於零。 – scorpiozj 2011-05-12 03:04:23

相關問題