2011-04-04 68 views
0

可能重複:
Why setting to nil after releasing?釋放後是否將對象設置爲零所需?

以下哪些例子是正確的?我看到不同的程序員/應用程序以不同的方式做這件事,我只是想知道釋放對象的正確方式。釋放它後需要將對象設置爲零嗎?

API *api_handle = [[API alloc] init]; 
[api callmethod]; 
[api release]; 
api = nil; 

或者

API *api_handle = [[API alloc] init]; 
[api callmethod]; 
[api release]; 

換句話說,是否有必要設置對象爲nil釋放之後?如果不是,人們爲什麼這樣做?如果是這樣,那麼做什麼好處呢?

回答

5

這不是必需的本身但是,如果您使用的變量的範圍超過-release消息,那麼這是一個很好的做法。因爲它阻止你不小心將消息發送給解分配的對象

1

人做到這一點。發送消息給nil總是返回0/nil,但是發送消息給一個釋放對象會導致SIGSEGV處於最佳狀態,其他情況下難以預料的調試行爲很難。

1

取決於上下文。

  • 在dealloc?

個人選擇;一些做,一些不。如果你在dealloc,該對象已經有效死亡。除了更多的取消分配之外,不應該對該對象執行任何其他方法調用。

就我個人而言,我有時會將它們設置爲0x1以確保崩潰。在併發代碼庫中非常有用。

  • 其他地方?

將其設置爲nil。如果在一個實例(一個實例變量)中有一個對象引用,該實例的生命週期與對象本身分離,那麼您應該在賦值時保留該對象引用,並且在實例完成時釋放它並將其釋放。

這可以防止由於懸掛指針和過度版本導致的崩潰。

它也讓你做if (!transientObject) transientObject = ....懶惰的初始化沒有一個跟蹤變量(一個布爾或東西)。

0

這不是必需的,我也不認爲在釋放後將局部變量設置爲零是一種很好的做法,但我也不會將其標記爲不良做法。

將局部變量設置爲零肯定會使您遠離意外的EXEC_BAD_ACCESS,但這種缺陷很容易被XCode內置靜態分析器檢測到,並且在運行時已被NSZombieEnabled檢測到。此外,如果您修改代碼並提前設置爲零的引用,您將永遠不會看到崩潰,並且您認爲該代碼段的邏輯可能不正確,因爲您之後的代碼沒有按照您的想法執行是的,它永遠不會抱怨什麼。如果你已經在正確的位置釋放它,爲什麼還要把它設置爲零?如果在此之後添加更多的代碼以便稍後執行某些操作,則該代碼應該崩潰而不是默默跳過它,因爲那樣您就會知道出了問題。