我在分发构建中象征某些代码时遇到了麻烦,最后创建了一个简单的项目,该项目有一个按钮,它通过访问不存在的数组中的objectAtIndex而导致崩溃。
在发布(或分发)构建中,当符号化MyApp函数调用完全丢失时,跟踪会像这样出现:
0- CoreFoundation 0x34dcb29e __exceptionPreprocess + 158
1 libobjc.A.dylib 0x3537397a objc_exception_throw +26
2 CoreFoundation 0x34d16b70 -[__NSArrayM objectAtIndex:] + 160
3 UIKit 0x311a40a0 -[UIApplication endAction:to:from:forEvent:] + 68
4 UIKit 0x311a4052 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 26
5 UIKit 0x311a4030 -[UIControl sendAction:to:forEvent:] + 40
6 UIKit 0x311a38e6 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 498
...
在调试版本中,它显示了导致崩溃的代码的MyApp函数:
0 CoreFoundation 0x34dcb29e __exceptionPreprocess + 158
1 libobjc.A.dylib 0x3537397a objc_exception_throw + 26
2 CoreFoundation 0x34d16b70 -[__NSArrayM objectAtIndex:] + 160
3 MyApp 0x00098128 -[ViewController processArray] (ViewController.m:58)
4 MyApp 0x0009814e -[ViewController Crash:](ViewController.m:63)**
5 UIKit 0x311a40a0 -[UIApplication sendAction:to:from:forEvent:] + 68
6 UIKit 0x311a4052 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 26
7 UIKit 0x311a4030 -[UIControl sendAction:to:forEvent:] + 40
8 UIKit 0x311a38e6 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 498
在执行相同的部署和单击按钮测试后,上述跟踪不在设备日志中。
关于SO的一些文章/博客/问题已经谈到了符号化问题,其中显示了十六进制符号而不是方法名称等(这与此问题不同)并且我尝试从派生数据中删除内容,清理出构建目录等,但这可以一致地再现。任何人都可以解释为什么会发生这种情况。
编辑:添加代码以便于参考:
-(void) processArray
{
NSMutableArray *array = [NSMutableArray arrayWithObjects:@"One", @"Two", @"Three", nil];
[array objectAtIndex:3];//Intentional crash for testing
}
- (IBAction)Crash:(id)sender
{
[self processArray];
}
答案 0 :(得分:0)
尝试关闭编译器优化并在发布版本中重现崩溃。
我怀疑你被尾部调用优化所困扰。编译器可以直接从方法的末尾向JMP发出指令,直到调用任何方法。
即。在这种情况下:
- (void)boo
{
[self bangAGong];
}
由于没有返回值等,编译器可以重写对bangAGong
的调用,以便重用当前的堆栈帧。这称为尾调用(也是objc_msgSend()
的工作原理。通过这样做,它可以在返回时消除帧的弹出。
这使得您的代码运行速度稍快,但也意味着它似乎会从崩溃报告中删除堆栈帧。