<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span><span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">在开放app当中,闪退是最忌讳的事情,闪退的原因很多。最让人头疼的还是这个崩溃有时候发生,有时候不发生。</span>
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="white-space:pre"> </span>在ios当中,苹果提供了一套机制,方便开发者寻找闪退的根源。</span>
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="white-space:pre"> </span></span>
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="white-space:pre"> </span>在itunes中,可以下载崩溃日志。崩溃日志文件配合在app打包的时候生成dsym文件,就可以找到的崩溃的根源。</span>
首先,需要在build setting里面找到Debug Information Format,默认debug模式是不生成dsym文件的。两种方式获得这个生成这个文件,修改debug下也生成,把编译模式修改为release。(xxxxx.dsym文件会编译时生成,位置和xxxx.app同一目录)
模拟崩溃环境,此处认为制造一个崩溃方法。
- (IBAction)addbutton:(id)sender {
//屏幕当中设置一个按钮,点击按钮,进入该方法。无关代码就不贴了。
//点击这个按钮2次后,数组越界,程序崩溃。
NSArray *array = [[NSArray alloc] initWithObjects:@"1", @"2", nil];
static int i = 0;
NSLog(@"%@", array[i++]);
}
1.接下来就是重点了,如果崩溃发生在测试环节,直接把手机接入当初生成该app的那台电脑(崩溃日志文件需要找到对应的dsym文件,才能定位崩溃位置)。在xcode的菜单栏找到window->devices->iPhone手机->view Device logs.此时会自动入读手机当中的所有崩溃日志,找到我们需要的,一般就是项目名称。
崩溃日志里面就记录我们需要的东西,例如,进程名称,硬件类型,工程bouldid,版本号,时间。找到如下代码,这个就是最后异常堆栈信息,可以看到一层一层的调用。
可以看到,在序号为3.4行的地方,ViewController.mm这个文件调用addbutton这个方法后,数组访问objectAtindex这个地方出问题了,反复检查。进行就可以就行了。方法后面的+ 196,表示的偏移量,以字符为单位。
Last Exception Backtrace:
0 CoreFoundation 0x18254d900 __exceptionPreprocess + 124
1 libobjc.A.dylib 0x181bbbf80 objc_exception_throw + 56
2 CoreFoundation 0x182433ac4 -[__NSArrayI objectAtIndex:] + 196
3 background 0x1000140a4 -[ViewController addbutton:] (ViewController.mm:55)
4 UIKit 0x187277e50 -[UIApplication sendAction:to:from:forEvent:] + 100
5 UIKit 0x187277dcc -[UIControl sendAction:to:forEvent:] + 80
6 UIKit 0x18725fa88 -[UIControl _sendActionsForEvents:withEvent:] + 416
7 UIKit 0x1872776e4 -[UIControl touchesEnded:withEvent:] + 572
8 UIKit 0x187277314 -[UIWindow _sendTouchesForEvent:] + 804
9 UIKit 0x18726fe30 -[UIWindow sendEvent:] + 784
10 UIKit 0x1872404cc -[UIApplication sendEvent:] + 248
11 UIKit 0x18723e794 _UIApplicationHandleEventQueue + 5528
12 CoreFoundation 0x182504efc __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
13 CoreFoundation 0x182504990 __CFRunLoopDoSources0 + 540
14 CoreFoundation 0x182502690 __CFRunLoopRun + 724
15 CoreFoundation 0x182431680 CFRunLoopRunSpecific + 384
16 GraphicsServices 0x183940088 GSEventRunModal + 180
17 UIKit 0x1872a8d90 UIApplicationMain + 204
18 background 0x10001428c main (main.m:14)
19 libdyld.dylib 0x181fd28b8 start + 4
这种情况我们看到的是已经处理过后,我们可以直接定位。
2.有些情况下,我们获得崩溃日志是这些,
Last Exception Backtrace:
(0x18254d900 0x181bbbf80 0x182433ac4 0x1000900a4 0x187277e50 0x187277dcc
0x18725fa88 0x1872776e4 0x187277314 0x18726fe30 0x1872404cc 0x18723e794
0x182504efc 0x182504990 0x182502690 0x182431680 0x183940088 0x1872a8d90
0x10009028c 0x181fd28b8)
一看全部是地址,并不能定位到崩溃所在的地方。接下来,就需要用到打包生成的文件 xxx.app, xxx.app.dsym这2个文件了。
接下来,新建一个目录,把这3个文件复制到一个目录下。
打开控制台cd到当前目录,在得到结果之前,我们还需要一个工具,symbolicatecrash。这个工具是xcode自带的,需要在xcode的包里面找到他,由于版本不同,这里我们先命令行定位,可以搜索,随便你啦。控制台输入:
find /Applications/Xcode.app -name symbolicatecrash -type f
会显示这个工具的位置,把他复制到同上面3个文件的所在目录当中。
在命令行输入代码,把东西翻译一次,得到我们想要的东西。
./symbolicatecrash ./backgroud.crash ./background.app.DSYM > symbol.crash
此处可能会报错,
Error: "DEVELOPER_DIR" is not defined at ./symbolicatecrash line 69.
那在输入./symbolicatecrash之前,加一行命令
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
重新输入过后,就会得到一个文件symbol.crash,这个文件的内容就和方法1一样,可以看到堆栈信息了。
3.后记
我们从itunes上面下载的日志,是用户上传的。这个可以很大的帮助开发者。这个得用户自愿,在手机的设置里面,用户可以设置此项,不上传日志。具体方法为:设置-》隐私-》诊断与用量-》。选择不发送或者自动发送,还可以直接浏览到日志。