当在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)
评估NO,但在访问[thisZombie target]
中的整数时抛出错误的访问权限?
target
是指向NSObject(zombified)
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]:发送到解除分配的实例0x2108f0的消息”
我想我应该提一下这个游戏有“僵尸”,不要与“NSZombie”混淆
因此,程序将“thisZombie.target”评估为“true” 但当我去访问“thisZombie.target.x”时,程序停止执行。
为什么?
编辑3
大家好, 我再次感谢大家的有益评论和建议。 我决定通过彻底改变我的僵尸跟随领导者的方式来解决这个问题。
我仍然不知道如上所述会导致评估的原因,但不再需要答案。
答案 0 :(得分:1)
我写这篇博客是为了帮助理解和调试EXC_BAD_ACCESS
http://loufranco.com/blog/files/Understanding-EXC_BAD_ACCESS.html
为了方便
运行构建和分析 - 你得到一个干净的构建?看看它在说什么,但你现在可以忽略泄漏问题 - 寻找向已发布对象发送消息的问题
使用NSZombiesEnabled运行 - 这会使对象永远不会释放,然后在向retainCount为0的对象发送消息时进行投诉。
启用Guard Malloc,然后使用特殊的GDB命令检查堆的完整性。问题是你需要在崩溃之前单步执行此操作以找到真正的问题。尽管
编辑:根据您的上述信息。您已取消分配thisZombie.leader
,但未将其设置为nil。也许,你忘了让这个僵尸保留它,所以它很早就被解除了分配。
如果有循环引用(僵尸指向领导者和领导者指回),这可能会很棘手。如果它不是循环的,请记住保留您设置属性的任何对象以指向(如果您使用保留属性并且记得始终使用属性语法,则自动)
答案 1 :(得分:0)
即使对象显示内存位置并不意味着它有效。它可能被释放,你只是拿着指向垃圾的指针。
答案 2 :(得分:0)
您需要检查您的数组或其他变量是否已初始化。使用NSLog或断点可以帮助您找到导致此错误的确切变量。如果是因为传递或返回了某些参数,那么Max建议的原因也是有效的。
如果您可以发布代码,那将有助于找到确切的问题。