2010-09-27 143 views
4

這是一段代碼,我寫在Xcodeiphone內存管理奇怪的問題

Foo * myFoo = [[Foo alloc] init] ; 

[myFoo release] ; 
[myFoo printMessage] ; 

如果我是正確的,它應該給一個運行時錯誤時,如myFoo獲取到那個時候釋放printmessage函數被調用。但在xcode中,代碼正在運行,打印消息正在調用,是否因爲在xcode上設置了問題?

問候 作者Abhijit

回答

7

你通過訪問釋放的內存調用未定義的行爲。

它可能會崩潰,它可能正常工作,它可能會導致舞會獨角獸從你的鼻子噴出。

來檢測內存錯誤,而你正在開發的代碼,您應該啓用NSZombie的,在這裏看到的說明:

http://www.cocoadev.com/index.pl?NSZombieEnabled

更新

你可能會問,爲什麼它是這樣工作的 - 肯定當您嘗試訪問無效的內存時,操作系統應該始終引發錯誤?

你不總是得到一個錯誤(以及爲什麼行爲是未定義的)的原因是檢查內存在每次訪問都是有效的會導致性能損失 - 即。代碼會運行得更慢,只是爲了檢查一些不該發生的事情。

因此,您在開發過程中必須注意捕獲所有這些錯誤,以免它們發生在最終用戶身上。 NSZombies是找到它們的最佳工具。另一點 - 如果你在xcode中「建立和分析」,它也可能在編譯時找到這個錯誤。當然,靜態分析器會在構建時檢測到一些內存錯誤。

+0

+1雖然我一個人不喜歡從人的鼻子噴出。 – BoltClock 2010-09-27 12:16:21

+0

嗯...好吧,那麼這個未定義的行爲在設備和模擬器上都有效,我希望應用程序應該拋出一個異常或發送一條消息,如「在釋放實例上調用消息? – abhijit 2010-09-27 12:17:54

+0

您希望發生某些事情,但未定義的行爲意味着甚至編譯器或您的程序也不會確切地知道將消息發送到已發佈對象時會發生什麼。在這種情況下,我猜測有時候釋放不會立即發生。 – BoltClock 2010-09-27 12:19:15

0

發佈對象不是即時的,對象將被釋放,但不能確定是否發送釋放消息。你遇到的行爲是正常的。

+0

雖然你在一般情況下是正確的,但在這個問題給出的具體代碼中,我相信dealloc調用將在發佈調用中同步發生 - 所討論的對象從不自動發佈,因此不能在autorelease池中。 (我想在技術上init調用可能已經進入autorelease池,但我認爲這是不尋常的,如果它。)但是,我應該在我的答案中提到它:) – JosephH 2010-09-27 12:24:38