如何在Xcode4中调试"发送到deallocated instance的消息"?

don*_*ile 49 iphone xcode memory-management ios xcode4

我按下了ALT + CMD + R并在Arguments> Environment Variables中激活了NSZombieEnabled.此外,我在诊断>内存管理>启用僵尸对象中激活它.

但是,当我构建并运行时,在某些时候我的应用程序崩溃,在控制台中给我这个无用的消息:

*** -[CALayer retainCount]: message sent to deallocated instance 0x656b260
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪也没用.我将细节级滑块一直向右移动.线程1只是告诉我这个:

截图

一切都是系统所有,并没有一行与我的应用程序相关.所以很明显NSZombiesEnabled不能像在Xcode 3中那样工作,它停在死对象上.

有没有办法弄清楚哪个 CALayer过早解除分配?

更新:因此,在建立和运行大约100次后突然问题消失了!它完全消失了!最好的部分:我没有以任何方式修改我的代码!在中间我用clean命令清理了build文件夹和项目几次,并在Simulator中删除了几次app.

更新2:幸运的是问题再次出现.而现在似乎持久.幸运的是,因为我更喜欢找到根本原因,而不是随意地烦扰用户.

更新3:最后偶然发现它:

startButton = newBttn;
Run Code Online (Sandbox Code Playgroud)

本来应该:

self.startButton = newBttn;
Run Code Online (Sandbox Code Playgroud)

startButton是一个保留属性,在-dealloc我发布了它.因此,它在大多数(但不是全部)情况下得到了过度释放,在视图消失之后它崩溃了,给出了奇怪的CALayer retainCount消息.

Zombies Instrument(CMD + I)最终指出它与按钮有关.只是不知道为什么和在哪里.

Clang Static Analyzer没有抱怨这个明显的故障.

Jef*_*ley 98

如果再次出现,您可以运行专用的僵尸乐器.按Command + I来分析应用程序并选择Zombies仪器(您必须在模拟器上运行).如果你得到一个僵尸,你可以显示该对象的整个记忆历史(每个保留/释放),这对追踪错误非常有帮助.

  • 还是有效.并且也在设备上工作.;) (5认同)
  • 这让我很开心。我不知道你可以分析这样的应用程序。你不知道我现在有多开心。 (2认同)
  • 需要更多关于“如果你遇到僵尸,你可以......”的细节。我在 Instruments 下启动了我的应用程序,选择 Zombies,点击启动我的应用程序的“录制”按钮,按照必要的步骤导致僵尸崩溃,我的应用程序此时停止运行(图标从 Dock 中消失),并且 Instruments 停止录制但显示没有错误消息。最终我发现了紫色的小旗,点击它,然后沿着箭头看到历史记录。事实证明,单击“未配对”有助于缩小关键事件的范围。 (2认同)

cho*_*own 53

除了杰夫的好答案; 做几乎相同的事情,但无需打开仪器或配置您的应用程序,您可以在调试器中设置NSZombieEnabled,MallocStackLoggingguard malloc.然后,当您的应用程序崩溃时,在gdb控制台中键入:

(gdb) info malloc-history 0x543216
Run Code Online (Sandbox Code Playgroud)

替换0x543216为导致崩溃的对象的地址,您将获得更有用的堆栈跟踪,它应该帮助您查明代码中导致问题的确切行.

本文还有一些额外的信息.

  • 仅供参考:使用LLDB调试器,您可以执行以下操作:(lldb)脚本导入lldb.macosx.heap(lldb)malloc_info --stack-history 0x7c506a00 (29认同)
  • 加载脚本的LLDB命令实际上是`command script import lldb.macosx.heap`(注意第一个单词).这将响应类似"malloc_info","ptr_refs","cstr_refs"和"objc_refs"命令的安装,使用这些命令的"--help"选项获取详细帮助.如果它正常工作 (18认同)