ARC 的 main() 中的 EXC_BAD_ACCESS 但没有提示错误

Posted

技术标签:

【中文标题】ARC 的 main() 中的 EXC_BAD_ACCESS 但没有提示错误【英文标题】:EXC_BAD_ACCESS within main() with ARC but no hint on the error 【发布时间】:2012-03-01 08:06:47 【问题描述】:

我的想法不多了。我在使用 ARC 的项目中收到EXC_BAD_ACCESS。根据调试器,它在main() 内。 NSZombieEnabled 设置为 YES 但我没有看到任何调用堆栈或类/类型或任何东西。检查员/个人资料也是如此。我得到的只是应用程序崩溃后的某个时间“会话超时”。

而且在我的代码中很难找到。

我正在设置类似的跟踪

NSLog(@"CrashLog: <%@:%@:%d:%s>", NSStringFromClass([self class]),
NSStringFromSelector(_cmd), __LINE__, __FILE__);

我的所有代码都在方法的入口和出口上,但我还没有发现任何有用的模式。我所能看到的是,当EXC_BAD_ACCESS 被抛出时,我所有有问题的方法都已经被留下了。

关于如何隔离问题的任何想法?

Tim 建议在 gdb 中使用回溯 (bt)。结果是:

#0  0x0be87580 in TI::Favonius::BeamSearch::choose_hit_test_node ()
#1  0x0be87b5f in TI::Favonius::BeamSearch::update_for_touch ()
#2  0x0be8ee32 in TI::Favonius::StrokeBuildManager::update_search_for_touch ()
#3  0x0be8f58f in TI::Favonius::StrokeBuildManager::key_down_or_drag_hit_test_for_UI ()
#4  0x0be6ba8b in TIInputManagerZephyr::simulate_touches_for_input_string ()
#5  0x0be7e5d9 in -[TIKeyboardInputManagerZephyr candidates] ()
#6  0x00678345 in -[UIKeyboardImpl generateAutocorrectionReplacements:] ()
#7  0x007dcaec in __71-[UITextInteractionAssistant scheduleReplacementsForRange:withOptions:]_block_invoke_0 ()
#8  0x007f6db2 in -[UITextSelectionView calculateAndShowReplacements:] ()
#9  0x00e255fd in __NSFireDelayedPerform ()
#10 0x01a03976 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ ()
#11 0x01a03417 in __CFRunLoopDoTimer ()
#12 0x019667e0 in __CFRunLoopRun ()
#13 0x01965dd4 in CFRunLoopRunSpecific ()
#14 0x01965ceb in CFRunLoopRunInMode ()
#15 0x01ccb879 in GSEventRunModal ()
#16 0x01ccb93e in GSEventRun ()
#17 0x0050d38b in UIApplicationMain ()
#18 0x000033e0 in main (argc=1, argv=0xbffff5fc) at /Users/Hermann/AppDev/fcApp/fcApp/main.m:16

【问题讨论】:

【参考方案1】:

仍有一些方法可以通过 ARC 获得 EXC_BAD_ACCESS。我遇到的一些

    1234563一个例子是 UIImagePicker——你不能只创建一个本地图像选择器变量并调用它(然后在它回调你时释放它)——你必须创建一个属性并保留它李>

    如果你不总是使用属性来保持它,你可能会遇到麻烦 - ARC 使用强弱的存在来知道该怎么做 - 如果你使用 ivar 代替,你可能会愚弄 ARC(对此不是 100% 肯定)。确保您不这样做的一种简单方法是使用 @synthesize var = _var 而不是让属性和 ivar 具有相同的名称。这样一来,如果你忘记了self.var = obj,而只使用var = obj,它就会报错。

    我在手势和标签中遇到了一个错误——标签视图没有保留 IB 添加的手势——我在这里记录了它

Crash when using gesture recognizers in StoryBoard

在这些情况下,Zombies 应该提供帮助 - 所以它没有帮助意味着您可能不会过早地导致发布发生。更有可能您正在使用内存——我会检查所有强制转换以及您使用内置数组或非对象指针的任何地方,以确保您不会越界。 Guard Malloc 可以提供帮助

https://developer.apple.com/library/ios/#documentation/Performance/Conceptual/ManagingMemory/Articles/MallocDebug.html

【讨论】:

谢谢娄。对于 1. 我正在处理异步 http 请求。但是,我很确定我在请求对象的调试方法中取消了所有打开的连接。但是我会仔细检查。 2.:谢谢。我会检查我是否在所有相关情况下都使用了 self.var。 3.根本不应该适用于我的应用程序。但是,您能否更具体地了解“guard malloc”。这对我来说要么是新闻,要么我真的不明白你的意思。 (英语不是我的母语)。到目前为止,谢谢。 点击 Guard Malloc 帮助的链接。它使堆对问题更加敏感。 这不是直接的帮助。然而,遵循建议大大缩小了及时窗口。如果您至少有一个想法,那么找到一些根本原因会容易得多,至少要查看或寻找什么。你正在运行一个很棒的博客。 :) 很高兴它有帮助。问题最终是什么? 啊,谢谢你的#1!这正是造成我的原因。【参考方案2】:

好吧,我终于明白了 - 几乎。

我还不知道哪个细节有误。最后我发现这个问题与 UITextView 有关。最初,文本视图并不是可编辑的。但我想接收触摸事件。所以我遵循了hiere给出的建议之一: (iPhone) How to handle touches on a UITextView? 我将“self”(一个 UIViewController 子类)指定为 UITextView 的委托,并且几乎没有以这种方式实现协议:

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
    [self userShow:nil]; //Within this method a subsequent UIViewController subclass/object is created and pushed.
    return FALSE;


- (BOOL)textViewShouldEndEditing:(UITextView *)textView
    return TRUE;


- (void)textViewDidBeginEditing:(UITextView *)textView
    return;


- (void)textViewDidEndEditing:(UITextView *)textView
    return;



- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
    return TRUE;


- (void)textViewDidChange:(UITextView *)textView
    return;


- (void)textViewDidChangeSelection:(UITextView *)textView
    return;

其目的实际上是避免编辑,但在用户触摸 UITextView 区域并调用某些操作时接收事件。在这种情况下,创建了一些后续视图控制器并将其推送到导航堆栈。它运行良好,但一段时间后,在某些情况下,几分钟(!)应用程序崩溃了。感谢 Lou 的回答和他的博客,我能够让 EXC_BAD_ACCESS 更接近 textViewShouldBeginEditing 的调用。与绕过 EXC_BAD_ACCESS 的早期绝望尝试类似,我注释掉了 UITextView 并调用了要使用其他一些 UIButton 项调用的视图控制器。 (只是一个快速的临时解决方法) 幸运的是,这成功了。该应用程序不再崩溃。现在我将寻求一些更复杂的实现,它们将带来相同的用户体验,但以不同但保存的方式调用另一个视图控制器。

我提供这个答案,以防其他人遇到同样的问题。如果您手头有关于究竟是哪个细节导致问题的解释,那么您的命中将受到高度赞赏。

【讨论】:

【参考方案3】:

尝试使用仪器(产品 > 配置文件)运行您的应用并选择泄漏模板。它可能会提示您错误在哪里。 More information here

【讨论】:

对不起,我没有提到我已经这样做了。还是谢谢。【参考方案4】:

听起来您没有设置异常断点。 Xcode 默认不会创建一个。打开Breakpoints Navigator (cmd+6),点击左下角的+,在弹出的菜单中选择“Add Exception Breakpoint”。单击“完成”,您应该会发现您现在已接近问题所在的位置。

如果没有这个,您通常会发现调试器将您转储到 main,而堆栈跟踪中没有提示您是如何到达那里的。

【讨论】:

不,这并没有让我更进一步。完全没有变化。

以上是关于ARC 的 main() 中的 EXC_BAD_ACCESS 但没有提示错误的主要内容,如果未能解决你的问题,请参考以下文章

iOS autoreleasepool in main 和 ARC alloc 发布

ARC机制集合内存管理

iOS通过ARC管理内存(内容根据iOS编程编写)

oc55--ARC单个对象的内存管理

oc56--ARC多个对象的内存管理

方便的构造函数 ARC 目标 c