【问题标题】:Objective-C "message sent to deallocated instance 0x5633b0"Objective-C“发送到已释放实例 0x5633b0 的消息”
【发布时间】:2010-10-10 16:58:05
【问题描述】:

我的 obj-C 应用程序中似乎有一些过分热心的发布 - 收到错误消息

"-[myobj release]: 消息发送到释放的实例 0x5633b0"

。我知道导致问题的对象实例的类,但是这个类被用来创建许多实例。

我的想法是我可以在类的 init 方法中添加一些日志记录,以记录任何“0x5633b0”对应的内容,这将有助于我跟踪创建实例的位置。

“0x5633b0”到底是什么?有什么方法可以在代码中访问该值来记录它?

谢谢。

【问题讨论】:

    标签: iphone objective-c


    【解决方案1】:

    当我最近遇到类似问题时,最适合我的是以下几点:

    1. Project->Edit Active Executable -> Arguments tab -> Environment variables 部分下,我添加并设置为YES 以下变量:NSAutoreleaseFreedObjectCheckEnabledNSZombieEnabledNSDebugEnabled.

    2. 在“运行”菜单下,我选择了启用 Guard Malloc

    通过这些设置,调试器提供了更多关于我的代码有什么问题的提示。

    (我找到了这些提示here

    祝你好运, 奥利

    【讨论】:

    • Enable Guard Malloc 在设备上调试时不起作用,至少我不能和这篇文章确认它:discussions.apple.com/thread/1572993?start=0&tstart=0
    • @JeroenEijkhof 是对的。 Guard malloc 在设备中不起作用。它们可以在“诊断”选项卡中启用,无需在 env var 中设置。但是 NSAutoreleaseFreedObjectCheckEnabled 可能需要设置为 env var。
    【解决方案2】:

    0x5633b0 可能是相关对象的地址(self 的值)。您可以使用NSLogprintf%p 进行打印。

    【讨论】:

    • 就是这样 - 我只需要一种方法来以某种方式获取对象的地址。我补充说: NSLog(@"INIT %p", self);到我的 init 方法,并能够判断哪个实例导致了问题。谢谢。
    • 您可以在“-[_NSZombie methodSignatureForSelector:]”中添加断点,以便在记录“发送到已释放实例的消息...”时停止调试器。
    • hey kenji 你能帮忙[_NSZombie methodSignatureForSelector: 举个例子
    【解决方案3】:

    0x5633b0 可能是被释放对象的地址(myobj 的值)。您可以使用NSLogprintf%p 进行打印。

    您还可以使用仪器分析器来查找已释放的对象。

    1.启动分析器:

    2。选择“僵尸”并启动分析器。

    3.单击模拟器,直到您遇到“解除分配的错误案例”

    【讨论】:

    • 为什么你的答案开头完全复制了@LoganCapaldo的答案?
    • 我一定是抄袭了它,再也没有回头。谢谢指出。我在那里添加了更多解释。
    • 三年后:谢谢!
    【解决方案4】:

    在调试器中,输入info symbol 0x5633b0,您会得到一些关于它是什么对象的指示。可能有用的另一件事是backtrace,它将为您提供堆栈跟踪。总而言之,this blog entry 有一些很棒的提示。

    【讨论】:

    • lldbimage lookup --address 0x1ec4 或短版im loo -a 0x1ec4
    【解决方案5】:

    您也可以将这些添加到环境变量中:
    MallocStackLoggingNoCompact 1

    并在 gdb 控制台中写入:
    info malloc-history <paste-address-here>

    参考:here

    【讨论】:

      【解决方案6】:

      考虑using the NSZombieEnabled flag

      然后您将知道您要发送消息的这个已释放对象是什么。

      【讨论】:

        【解决方案7】:

        你没有正确管理你的内存——你在某个对象上调用release/autorelease的次数比你调用retain的次数多。确保您遵守Memory Management Programming Guide for Cocoa 中列出的所有规则。

        0x5633b0 只是存储对象的内存位置的地址。您可以尝试做的一件事是在init 方法中添加一些代码:

        - (void) init
        {
            if(self == (MyClass*)0x5633b0)
                NSLog(@"Allocated object at address 0x5633b0");  // put a breakpoint on this line
            // do rest of init...
        }
        

        如果您有任何其他 init 方法(例如,initWithCoder:,它会为从 XIB 实例化的对象调用),请确保也将此 sn-p 放入这些方法中。在NSLog 行上放置一个断点,然后查看它何时被击中。请注意,如果一个对象在该地址分配、释放,然后另一个对象恰好在同一地址重新分配,它可能会被多次命中。崩溃前的最后一击是您想要的。

        【讨论】:

        • 如何事先知道符号的地址?是不是每次运行代码都不一样。至少这是我注意到的。在调试器控制台中使用“信息符号 0xabcdfg”之类的东西给了我比你的建议更好的结果。
        猜你喜欢
        • 2011-06-16
        • 2023-03-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多