我被一个我无法弄清楚如何调试的错误所困扰。基本上我在模拟器上运行我的代码,一切都很好。
但是当我转到实际设备时,我收到一个EXC_BAD_ACCESS错误。不幸的是,当在调试器下运行手机时该死的东西工作正常,所以我无法判断错误发生的位置。
我确实得到了一个我无法重现的堆栈跟踪,所以我很确定我的代码中导致问题的那一行就是这一行(但是我不能在我的生活中弄清楚如何它可能是):
[[NSNotificationCenter defaultCenter] postNotificationName:@"SubscriberChanged" object: nil];
实际错误发生在objc_msgSend大约这一行下面的四帧,但它的代码似乎是iPhone SDK的一部分,所以我没有来源检查它。
任何人都可以给我一些指示,告诉我如何找出这个问题的位置?我有一个发布这个东西的截止日期,我不能让它像这样出去......
我终于设法在调试器中重现了这一点。我得到的堆栈跟踪如下:
#0 0x30011940 in objc_msgSend ()
#1 0x3054dc80 in _nsnote_callback ()
#2 0x3024ea58 in _CFXNotificationPostNotification ()
#3 0x3054b85a in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#4 0x3054dbc0 in -[NSNotificationCenter postNotificationName:object:] ()
#5 0x000027c6 in -[My2CentsAppDelegate handleMOCChange:] (self=0x1159d0, _cmd=0x2bf90, notification=0x147400) at /Users/sdussin/Desktop/UPOD Research LLC/Development/My2Cents/Classes/My2CentsAppDelegate.m:52
#6 0x3054dc80 in _nsnote_callback ()
#7 0x3024ea58 in _CFXNotificationPostNotification ()
#8 0x3054b85a in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
堆栈跟踪中的第5帧对应于上面的行。
答案 0 :(得分:2)
如果您无法在调试器中重复崩溃,可以尝试其他方法来解决它:
特别是clang非常善于发现内存管理错误。 EXC_BAD_ACCESS闻起来就像一个。
您在NSNotificationCenter注册的观察员之一可能已被释放。记住,
重要:通知中心 不保留观察员, 因此,你必须确保你 取消注册观察员(使用 removeObserver:或 removeObserver:name:object :)之前 他们被解除分配。 (如果你不这样做, 如果,您将生成运行时错误 中心向被释放的人发送消息 对象。)
答案 1 :(得分:2)
您可以使用NSZombieEnabled(Google it)来跟踪此类事情。除此之外,我还是第二个:你可能需要取消注册一些观察者,例如已卸载但仍注册为观察者的视图控制器。
答案 2 :(得分:1)
崩溃正在发生,因为某些对象是为您发送的通知注册的,并且在发布之前没有取消订阅。因此,当您发送通知时,它会尝试回叫该对象,然后繁荣。
查看您订阅的代码中的所有位置,并查看您错过了取消订阅的位置(例如,您是否在dealloc中取消订阅?)。
同样如我们所提到的NSZombieEnabled = YES,您可以通过右键单击XCode项目浏览器中的可执行文件来设置环境标志,然后转到Arguments选项卡并将其添加到环境变量中。然后观察日志,当你发送通知时,你会看到一条消息,上面写着“消息blah发送到解除分配的实例”。
答案 3 :(得分:1)
大头钉跟踪告诉您注册了“SubscriberChanged”通知的对象已被解除分配。处理此问题的最简单方法是查找注册“SubscriberChanged”通知的所有类,并在[dealloc]方法中取消注册。
答案 4 :(得分:-1)
通常情况下,如果遇到某些情况,某些东西在模拟器上运行而不是在设备上运行,反之亦然,原因是库/框架没有针对它崩溃的处理器进行编译。
在您的情况下,您将拥有一个可在设备上正常工作的ARM库/框架,但在i386上运行的模拟器上崩溃。我会检查为该通知注册的任何对象的继承。