2010-09-27 123 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