我有一个滚动视图应用程序,它在模拟器上运行良好,但是,当安装在设备上时,当我尝试滚动一页时,它会给我一个
EXC_BAD_ACCESS
。我已经通过“分配和泄漏的工具”运行了它,但没有任何泄漏,也没有僵尸消息......我只是好奇什么会导致模拟器与设备之间存在如此大的差异?由于我的符号化崩溃日志(下面部分),任何调试此问题的方法似乎都不是非常符号化。
Exception Type: EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x0000000f
Crashed Thread: 0
Thread 0 Crashed:
0 libobjc.A.dylib 0x0000286e objc_msgSend + 18
1 MyApp 0x00004fee 0x1000 + 16366
2 UIKit 0x000668f4 -[UIViewController view] + 104
3 MyApp 0x00009716 0x1000 + 34582
4 MyApp 0x0000960c 0x1000 + 34316
5 UIKit 0x0001426c -[UIScrollView setContentOffset:] + 344
谢谢
模拟器中的代码可能存在错误,但幸运的是您取消引用的指针不在未映射的内存中,因此不会触发 EXC_BAD_ACCESS。 指针可能是坏的,并且被访问了,但没有被检测到——这仍然是一个错误。
您已经检查过没有收到任何僵尸消息,这将是我的第一个建议。
接下来要做的是启用 Guard Malloc——然后阅读本文
您只能在模拟器中执行此操作 - 您的目标是使用超敏感堆使错误在模拟器中抛出 EXC_BAD_ACCESS。
文章中:
设备上的错误访问可能由多种原因引起,其中大多数与设备的内存少于模拟器有关,因此它会更快地释放已释放的内存。
发现问题的最佳方法是在设备上以调试模式运行应用程序,而不使用断点(这样做的原因之一是添加断点,然后将其删除)。如果您可以通过这种方式重现错误的访问,则重现后,您可以查看调试器控制台(cmd+shift+y),您将看到程序已停止在类似断点的位置,然后进入线程堆栈查看您的应用程序执行和失败的最后一次调用,可能访问了错误的指针。
我想将我的案例添加到讨论中。我刚刚解决了一个与此非常相似的问题。它在模拟器上有效,但在设备上失败。以为是内存问题。事实并非如此。
结果我忘记了非空方法上的
return
。它应该返回一个值,但我完全忘记了返回。如果你问我,这是一个非常糟糕的错误,但它在模拟器中运行没有问题(即使返回实际上用于存储变量并用它做一些其他事情)。
不知何故,模拟器每次都能工作,但忘记了返回。这让我很困惑,但我只能疯狂地猜测它必须将我使用的最后一个变量放在返回应该指向的同一位置,从而导致错误(错误但正确)的返回。
然后在设备上运行,在正常情况下每次都会崩溃。我一步步调试才意识到我没有正确返回失败方法的结果。
希望它可以帮助任何面临这个问题的人!