在实例方法中,我在超类上调用相同的选择器并获得EXC_BAD_ACCESS。我正在使用手动引用计数(不是ARC),这发生在主线程中。静态分析报告没有问题,而不是我认为这意味着一个干净的健康状况。相关代码如下:
CommentListMedia.m(下面的跟踪中的堆栈帧1):
- (void)play {
if ((comments.isLoading) && (! comments.isLoaded))
playWhenLoaded = YES;
else [super play]; // <-- EXC_BAD_ACCESS happens here
}
MediaControls.m(下面的跟踪中的堆栈帧2):
- (void)play {
[media play]; // <-- this calls the code above
[self notifyWithName:MediaControlsDidPlayNotification];
}
MyApp.m(下面的跟踪中的堆栈框架11):
- (void)sendEvent:(UIEvent *)event {
[super sendEvent:event]; // <-- this calls the code above
...
}
CommentListMedia的超类是SequentialMedia,它没有计入堆栈跟踪,因为异常发生在它到达之前。
不幸的是,我只是在崩溃报告(来自Crashlytics)中看到了这一点,并且我自己无法重现它。令我感到奇怪的是,对类实例的引用必须首先执行播放选择器,但不知何故,当它到达结尾时,对超类的引用是不好的。起初我认为实例可能是自动释放的或者其他东西,但我的印象是在运行循环结束时主线程上发生自动释放,而不是在调用中间的某个随机时间。关于可能导致此问题或如何调试它的任何输入将不胜感激。
主线程上的调用堆栈如下所示:
0 libobjc.A.dylib objc_msgSend + 5
1 MyApp -[CommentListMedia play]
2 MyApp -[MediaControls play]
3 UIKit -[UIApplication sendAction:to:from:forEvent:] + 90
4 UIKit -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 30
5 UIKit -[UIControl sendAction:to:forEvent:] + 44
6 UIKit -[UIControl _sendActionsForEvents:withEvent:] + 374
7 UIKit -[UIControl touchesEnded:withEvent:] + 590
8 UIKit -[UIWindow _sendTouchesForEvent:] + 528
9 UIKit -[UIWindow sendEvent:] + 832
10 UIKit -[UIApplication sendEvent:] + 196
11 MyApp -[MyApp sendEvent:]
12 UIKit _UIApplicationHandleEventQueue + 7096
13 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 14
14 CoreFoundation __CFRunLoopDoSources0 + 206
15 CoreFoundation __CFRunLoopRun + 622
16 CoreFoundation CFRunLoopRunSpecific + 522
17 CoreFoundation CFRunLoopRunInMode + 106
18 GraphicsServices GSEventRunModal + 138
19 UIKit UIApplicationMain + 1136
20 MyApp main
答案 0 :(得分:1)
0 libobjc.A.dylib objc_msgSend + 5
1 MyApp -[CommentListMedia play]
可能在-[SequentialMedia play]
中崩溃。具体来说,如果该方法返回void
并作为方法中的最后一个表达式进行调用,则[optimize]编译器可能会生成尾调用。这将有效地导致方法调用从堆栈中消失。
从崩溃报告中发布寄存器的内容。 $ r0可能非常有启发性(因为它是第一个arg,应该是一个可行的对象)。
此外,如果程序中存在大量并发,则可能是对象正在被辅助线程释放和释放。但是,通常情况下,您会看到不止一种奇怪的崩溃(尽管有时不会,如果您的代码大量使用同步原语 - 并发程序在运行与运行之间的一致性可能非常显着)。