我的想法已经不多了。我在使用ARC的项目上收到EXC_BAD_ACCESS
。根据调试器,它在main()
之内。 NSZombieEnabled设置为YES但我没有看到任何callstack或Class / Type或任何东西。 Inspector / Profile也是如此。在应用程序崩溃后的某个时间,我得到的只是“会话超时”。
很难找到我的代码。
我正在设置像
这样的痕迹NSLog(@"CrashLog: <%@:%@:%d:%s>", NSStringFromClass([self class]),
NSStringFromSelector(_cmd), __LINE__, __FILE__);
我的代码中有关enty和退出方法,但我还没有找到任何有用的模式。我所能看到的是,当EXC_BAD_ACCESS
被抛出时,我所有的方法都已经被遗弃了。
关于如何隔离问题的任何想法?
Tim建议在gdb中使用back trace(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
答案 0 :(得分:12)
仍然有办法通过ARC获得EXC_BAD_ACCESS。我碰到的一些
如果您正在做一个制作对象的东西并且异步调用回来 - 您必须确保在某处保留对它的引用,否则ARC将释放它。一个例子是UIImagePicker - 你不能只创建一个本地图像选择器变量并调用它(然后在它回调时释放它) - 你必须创建一个属性并保持它
如果你不总是使用属性来抓住它,你可能会遇到麻烦 - ARC使用强弱的存在来知道该怎么做 - 如果你使用ivar代替,你可能会欺骗ARC(不是100%肯定这一点)。确保不执行此操作的一种简单方法是使用@synthesize var = _var
而不是让属性和ivar具有相同的名称。这样,如果您忘记self.var = obj
并且只使用var = obj
,就会抱怨。
我在手势和标签中遇到了一个错误 - 标签视图没有保留IB添加的手势 - 我在此处记录了
Crash when using gesture recognizers in StoryBoard
在这些情况下,僵尸应该提供帮助 - 所以它没有帮助意味着你可能不会过早地导致释放发生。更有可能是你正在调整内存 - 我会检查所有强制转换以及你使用内置数组或非对象指针的任何地方,以确保你不会超出界限。 Guard Malloc可以提供帮助
答案 1 :(得分:1)
好吧,最后我知道了 - 奈利。
我还不知道哪个细节错了。最后我发现问题与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的earler绝望的注意事项我注释掉了UITextView并调用了使用其他UIButton项调用的视图控制器。 (只是一个快速的解决方法) 幸运的是,这样做了。该应用程序不再崩溃。现在我将进行一些更复杂的实现,它将带来相同的用户体验,但以另一种方式调用另一个视图控制器。
我提供这个答案,以防其他人遇到同样的问题。如果您有关于哪个细节确切导致问题的解释,那么您的热门歌曲将受到高度赞赏。
答案 2 :(得分:0)
尝试使用乐器(Product&gt; Profile)运行app,然后选择Leaks模板。它可能会提供有关错误位置的提示。 More information here
答案 3 :(得分:0)
听起来你没有设置异常断点。 Xcode默认不创建一个。打开Breakpoints Navigator(cmd + 6),单击左下角的+,然后从弹出的菜单中选择“Add Exception Breakpoint”。点击“完成”,您会发现现在已经接近问题所在。
如果没有这个,你经常会发现调试器会将你转储到main
中,而不会在堆栈跟踪中提示你如何到达那里。