【问题标题】:iphone memory management strange issueiphone内存管理奇怪的问题
【发布时间】:2010-09-27 12:10:10
【问题描述】:

这是我用 xcode 写的一段代码

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

[myFoo release] ;
[myFoo printMessage] ;

如果我是对的,当调用 printmessage 函数时它应该会给出一个运行时错误,因为此时 myFoo 被释放了。但是在 xcode 中,代码正在运行并且打印消息被调用,这是由于 xcode 上的设置而导致的问题吗?

问候 阿比吉特

【问题讨论】:

    标签: iphone objective-c nszombie


    【解决方案1】:

    您通过访问已释放的内存来调用未定义的行为。

    它可能会崩溃,它可能会正常工作,它可能会导致跳舞的独角兽从你的鼻子喷涌而出。

    要在开发代码时检测内存错误,您应该启用 NSZombie,请参阅此处的说明:

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

    更新

    您可能想知道为什么它会这样工作 - 当您尝试访问无效的内存时,操作系统肯定总是会抛出错误?

    您并不总是收到错误(以及行为未定义的原因)的原因是检查内存在每次访问时是否有效会导致性能损失 - 即。代码会运行得更慢,只是为了检查不应该发生的事情。

    因此,您必须在开发过程中小心捕捉所有这些错误,以免它们发生在最终用户身上。 NSZombies 是寻找它们的最佳工具。

    另外一点 - 如果您在 xcode 中进行“构建和分析”,它也可能在构建时发现此错误。当然,静态分析器会在构建时检测到一些内存错误。

    【讨论】:

    • +1 虽然我不想从别人的鼻子里吐出来。
    • hmm... 好的,未定义的行为在设备和模拟器上都有效吗,我希望应用程序应该抛出异常或发送消息,例如“在释放的实例上调用消息?”
    • 您期望某些事情会发生,但未定义的行为意味着即使是编译器或您的程序也无法确定当您向已发布对象发送消息时实际发生了什么。在这种情况下,我猜有时释放不会立即发生。
    • 未定义的行为就是这样 - 它没有定义会发生什么。如果您启用 NSZombies(您应该只在开发期间执行此操作,而不是在向客户发布时执行此操作),这将导致“在解除分配的实例上调用选择器”类型消息。我会在我的答案中添加更多细节。
    【解决方案2】:

    释放一个对象不是一蹴而就的,对象会被释放,但不能确定是在何时发送释放消息。您遇到的行为是正常的。

    【讨论】:

    • 虽然您通常是正确的,但在此问题中给出的特定代码中,我相信 dealloc 调用将在 release 调用中同步发生 - 有问题的对象从未自动释放,因此不能在自动释放池。 (我猜从技术上讲,init 调用本可以将它放入自动释放池中,但如果确实如此,我会认为这很不寻常。)不过,我应该在回答中提到它 :)
    猜你喜欢
    • 1970-01-01
    • 2011-01-07
    • 2011-04-11
    • 1970-01-01
    • 1970-01-01
    • 2011-06-06
    • 2016-06-27
    • 1970-01-01
    • 2010-10-20
    相关资源
    最近更新 更多