102

我已经看到建议说要NSZombieEnabledtrue调试时设置。什么是 NSZombie?它是一个框架吗?设定?

4

4 回答 4

203

它是一种内存调试辅助工具。具体来说,当您设置NSZombieEnabledthen 时,只要一个对象达到保留计数 0,而不是被释放,它就会将自己变形为一个NSZombie实例。每当这样的僵尸收到消息时,它会记录一个警告,而不是崩溃或以不可预测的方式表现。因此,您可以调试细微的过度释放/自动释放问题,而无需高级工具或在大海捞针中进行艰苦的搜索。

这个名字是一个相当明显的事实,即当对象达到保留计数 0 时通常被认为是“死的”。在这个设置下,它们继续存在于一个奇怪的半衰期 - 既不是活的,也不是完全死的。很像真正的僵尸,只是它们吃的大脑更少。

于 2010-11-12T19:34:05.413 回答
97

Adam 很好地解释了僵尸是什么,但使用环境变量并不是查找和跟踪僵尸的最佳方式。

一个更好的僵尸检测方法就是使用 Instruments - 从 XCode 开始,从“Run with Instrument”开始,然后选择“Allocations”。

然后在开始后立即停止记录,按 Allocations 工具上的“i”按钮,然后打开“启用引用计数”和“启用 NSZombie 检测”。现在再次点击仪器中的记录,您的应用程序将启动 - 如果发送任何僵尸对象消息记录将停止,并且在记录时间线中将弹出一个对话框 - 您可以单击它以查找对象所在的每个位置保留或释放。

编辑:以前的建议是针对 XCode 3,这里是 XCode 4 的补充:

在 XCode 4.2中,有一个更简单的机制来利用僵尸检测 - 僵尸仪器。而不是“运行”来启动应用程序,使用“配置文件”,仪器选择器会出现。选择“Zombie”,应用程序将开始运行 - 无论导致崩溃,都会弹出一个对话框,显示“Zombie Messaged”。

从那里,单击对话框中的小箭头。这将包含创建、保留或释放僵尸对象的所有时间的列表。拉起侧边栏,您可以转到每个条目,查看堆栈跟踪中负责保留计数中每次调整的代码。

于 2010-11-12T20:20:30.513 回答
32

我同意 Kendall 添加的内容,它非常有用,但我建议您仍然使用环境变量,这样您就不会忘记它们已启用。类似于 Cocoa Dev 的(现已过期)链接,我放了这个,所以我不会错过它:

if(getenv("NSZombieEnabled") || getenv("NSAutoreleaseFreedObjectCheckEnabled")) {
    NSLog(@"ZOMBIES/AFOC ARE ENABLED!!! AAAAARRRRRRGH!!! BRAINS!!!");
} 

它很好地引起了我的注意。

于 2010-11-13T06:04:20.830 回答
1

会帮助某人。

仪器的详细文件。 https://developer.apple.com/library/watchos/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/index.html#//apple_ref/doc/uid/TP40004652-CH3-SW1

于 2016-07-21T18:08:20.677 回答