【问题标题】:What causes "EXC_BAD_ACCESS" when calling a selector?调用选择器时导致“EXC_BAD_ACCESS”的原因是什么?
【发布时间】:2011-08-11 18:40:23
【问题描述】:

当在Objective-C中调用选择器,应用程序崩溃,导致调试堆栈指向选择器,这是什么原因?据我了解,这是由于内存错误造成的。但是,我将命令发送到的对象和参数(数组)都是有效的。我可以说出来,因为这两个对象在 Xcode 中鼠标悬停时会显示内存位置以及其他信息。

由于跟踪在这个选择器处结束,我很茫然。当堆栈指向具有有效对象参数的选择器时,我从未见过此错误。

此外,此选择器被频繁调用。它总是处理相同类型的对象,并且在我崩溃之前没有任何异常行为。
这种崩溃很少发生,每 10 分钟或更短时间发生一次。

由于我是新手程序员,选择器内的代码可能有问题。我经常这样比较对象指针:

if (thisObject.pointerToSomeObject == nil) { //do stuff...

我开始怀疑这是否是正确的 Objective-C 编程,但话又说回来,代码大部分时间都能正常工作。有没有我不知道的极端案例?

附加信息: 我正在使用 cocos2d 版本 1.0.0,Xcode 4.1。在 iPad 模拟器上进行测试。

感谢任何帮助,即使是相关调试文章的链接也会有所帮助。


编辑

发展:

指向选择器的默认调试线程,如果出现错误访问错误,则可能意味着错误访问发生在该选择器的执行过程中。可以使用 NSZombies 进一步调试以找到确切的行。

所以,在开启 NSZombies 之后,问题就更详细地暴露出来了。 (感谢@Lou Franco 的糟糕访问教程)

现在,会导致什么:

if ([thisZombie target] == nil)

评估否,但在访问[thisZombie target] 中的整数时抛出错误访问? target 是一个指向 NSObject(僵尸化)的指针

else {

  int diffx = [thisZombie x] - [[thisZombie target] x];
  //                                          ^^ ----- bad access here

** 编辑 2 **

语法或短路评估一定有问题:

if (!thisZombie.target && thisZombie.leader && !thisZombie.leader.dead)

thisZombie.leader.dead 停止线程: " * -[Zombie dead]: message sent to deallocated instance 0x2108f0"

我想我应该提到这个游戏有“僵尸”,不要与“NSZombie”混淆

因此,程序将“thisZombie.target”评估为“true” 但是当我访问“thisZombie.target.x”时,程序停止执行。

为什么?


编辑 3

大家好, 我想再次感谢大家的帮助和建议。 我决定通过彻底改变我的僵尸跟随他们的领导者的方式来解决这个问题。

我仍然不知道什么会导致如上所述的评估,但不再需要答案。

【问题讨论】:

    标签: objective-c ipad crash cocos2d-iphone exc-bad-access


    【解决方案1】:

    我写这篇博客是为了帮助理解和调试 EXC_BAD_ACCESS

    http://loufranco.com/blog/files/Understanding-EXC_BAD_ACCESS.html

    按顺序排列

    1. 运行构建和分析——你得到一个干净的构建吗?看看它在说什么,但你现在可以忽略泄漏问题——寻找向释放对象发送消息的问题

    2. 使用 NSZombiesEnabled 运行——这使得对象永远不会被释放,如果消息被发送到一个 retainCount 为 0 的对象时会报错。

    3. 启用 Guard Malloc,然后使用特殊的 GDB 命令检查堆的完整性。问题是您需要在崩溃之前逐步完成并执行此操作才能找到真正的问题。不过,它可能会在更接近您的问题的其他地方崩溃

    编辑:根据您上面的信息。你释放了thisZombie.leader,但你没有将它设置为nil。可能是你忘了让 thisZombie 保留它,所以它被提前释放了。

    如果有循环引用(僵尸指向领导者,领导者指向后面),这可能会很棘手。如果它不是循环的,请记住保留您设置属性指向的任何对象(如果您使用保留属性则自动并记住始终使用属性语法)

    In Objective-C on iOS, what is the (style) difference between "self.foo" and "foo" when using synthesized getters?

    【讨论】:

    • 我按照您的教程进行操作,它帮助很大。我相信我将来会使用我学到的东西。非常感谢!
    • @user890499 如果这是最好的答案并且对您有所帮助,那么请考虑单击旁边的那个小复选标记。这会将答案标记为“已接受”,以便未来的用户知道什么是有效的。
    • 它没有解决它,但它帮助缩小了问题和问题的范围。仍在寻找答案。
    • 我进行了编辑,我认为可以解决您的原始问题。如果将属性设置为对象,则需要保留。你可以很容易地再次引入这个问题——点击我关于保留属性和命名的建议的链接。
    【解决方案2】:

    即使对象显示内存位置并不意味着它是有效的。它可能已被释放,而您只是持有指向垃圾的指针。

    【讨论】:

    • 记录目标对象和单个参数(一个数组)给出详细的结果。我不相信这些会被取消分配。我已将日志添加到这些对象的 dealloc 方法以确保这一点。我没有意识到内存位置并不一定意味着它是有效的。谢谢
    【解决方案3】:

    您需要检查您的数组或其他变量是否已初始化。使用 NSLog 或断点可以帮助您找到导致此错误的确切变量。如果是因为某个参数的传递或返回,那么Max给出的理由也是成立的。

    如果您可以发布代码,这将有助于找到确切的问题。

    【讨论】:

      猜你喜欢
      • 2018-02-26
      • 1970-01-01
      • 2020-09-02
      • 2012-11-28
      • 2012-07-05
      • 1970-01-01
      • 1970-01-01
      • 2014-04-22
      • 1970-01-01
      相关资源
      最近更新 更多