我对iPhone开发和Xcode基本上是新手,不知道如何开始对EXC_BAD_ACCESS信号进行故障排除.如何让Xcode在导致错误的那一行中断?


我似乎无法让Xcode停止导致问题的那一行,但我确实在调试控制台中看到了以下几行:

10月25日星期日15:12:14 JasonMacBook

10月25日星期日15:12:14 JasonMacBook

10月25日星期日15:12:14 JasonMacBook

10月25日星期日15:12:14 JasonMacBook

2009-10-25 15:12:14.680

现在,我正在try 绘制从UIGraphicsGetCurrentContext()中检索到的上下文,并传递给我想要绘制的对象.


经过进一步的试错调试,我发现我的类上有一个属性的NSMutableArray是一个僵尸.我为这个类介绍了init函数,下面是我使用的代码:

if ((self = [super init])) {
        NSMutableArray *array = [NSMutableArray array];
        self.terrainBlocks = array;
        [array release];
    }
    return self;    
}

我删除了[array release]线,它不再给我EXC_BAD_ACCESS信号,但我现在不明白为什么这样做.我认为当我使用这个属性时,它会自动为我保留它,因此我应该在init之内释放它,这样我就不会有泄漏.我完全搞不懂它是如何工作的,我只读过的所有指南和Stackoverflow问题更让我搞不懂如何在init方法中设置属性.对于哪种方式最好,似乎没有达成共识.

推荐答案

对于任何EXC_BAD_访问错误,您通常会try 向已发布的对象发送消息.追踪这些信息的BEST种方法是使用NSZombieEnabled.

它的工作原理是,永远不会真正释放一个对象,而是将其包装为"僵尸",并在其内部设置一个标志,表明它通常会被释放.这样,如果你再次try 访问它,它仍然知道在你出错之前是什么,有了这一点信息,你通常可以回溯到问题所在.

在后台线程中,当调试器有时会浪费任何有用的信息时,它尤其有用.

然而,您需要VERY IMPORTANT TO NOTE%确保这只出现在调试代码中,而不是发布代码中.因为没有发布任何东西,你的应用程序会一个接一个地泄漏.为了提醒我这样做,我将此日志(log)放在我的appdelegate中:

if(getenv("NSZombieEnabled") || getenv("NSAutoreleaseFreedObjectCheckEnabled"))
  NSLog(@"NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled enabled!");

如果您需要帮助找到确切的行,请执行构建和调试(CMD-Y),而不是构建和运行(CMD-R).当应用程序崩溃时,调试器将准确地显示哪一行,结合NSZombieEnabled,您应该能够找到确切的原因.

Objective-c相关问答推荐

使用 NSMutableString 附加到文件的末尾

是否可以 suppress Xcode 4 静态分析器警告?

目标 C:在不离开应用程序的情况下发送Electron邮件

indexOfObject 对比indexOfObjectIdenticalTo

块引用作为Objective-C中的实例变量

判断 NSInteger 是奇数还是偶数

在 Xcode 5 中运行代码覆盖时出现数十个profiling:invalid arc tag

添加自定义 initWith?

奇怪的错误 NSAssert

了解按位与运算符

在 NSNumbers 的 NSArray 中查找最小值和最大值

主队列上的 dispatch_sync 与 dispatch_async

获取包含在 NSString 中的文件的扩展名

NSMutableArray 按顺序添加对象

NSCharacterSet:如何将_添加到 alphanumericCharacterSet 文本限制?

将 UIColor 保存到 NSUserDefaults 并从中加载

Objective-c 中 SEL 类型的属性

Objective-c 协议前向声明

如何在不管理 UDID 和重新编译的情况下无线分发 ios 应用程序

更改 UITextField 占位符字体