数组越界、空引用、引用未定义方法、内存空间不足等等。
如何获取crash闪退日志 -- 工具查看
先看第一个问题如何查看,我搜索的方法有以下几个:
第一个方法:XCode 的菜单Window->Organizer 选择Devices -> 选中的手机 -> 点击手机名称左边的箭头 会等到如下图
注意对比一下红色框框内容,这个日志也基本上上告诉你crash的原因了。
第二种方法 打开手机 - > 设置 -> 隐私 - > 诊断与用量 - > 诊断与用量数据 这里面就是所有应用的Crash日志。
第三种方法 通过iTunes Connect(Manage Your Applications - View Details - Crash Reports)获取用户的crash日志。方法很多这里不多列了。
解析crash
参见:http://stackoverflow.com/questions/1460892/symbolicating-iphone-app-crash-reports )
用程序获取crash日志
但是这里都是工具,没有用到程序获取,经过千方百计的查询(思路是:先找到存放crash的iphone系统路径:var/mobile/Library/Logs/CrashReporter)找到了crash存放的路径,唉,苦于无法读取(用程序读出来都是nil),当然如果是越狱手机就不一样是可以读取的。这个思路断掉了。
换个思路:自己用程序捕获crash,保存到本地可以吗?这么一试,果然........
第一步:新建一个继承自NSObject的类(Xcode新建一个空项目过程略),取名字CatchCrash,在h和m文件中写下:
.h文件
- #import <Foundation/Foundation.h>
- @interface CatchCrash : NSObject
- void uncaughtExceptionHandler(NSException *exception);
- @end
.m文件
1. #import "CatchCrash.h"
2. @implementation CatchCrash
3. void uncaughtExceptionHandler(NSException *exception)
4. {
5. // 异常的堆栈信息
6. stackArray = [exception callStackSymbols];
7. // 出现异常的原因
8. reason = [exception reason];
9. // 异常名称
10. name = [exception name];
11. exceptionInfo = [NSString stringWithFormat:@"Exception reason:%@\nException name:%@\nException stack:%@",name, reason, stackArray];
12. NSLog(@"%@", exceptionInfo);
13. tmpArr = [NSMutableArray arrayWithArray:stackArray];
14. [tmpArr insertObject:reason atIndex:0];
15. //保存到本地 -- 当然你可以在下次启动的时候,上传这个log
16. [exceptionInfo writeToFile:[NSString stringWithFormat:@"%@/Documents/error.log",NSHomeDirectory()] atomically:YES encoding:NSUTF8StringEncoding error:nil];
17. }
18. @end
第二步:添加一个继承自UIViewcontroller的类,取名字为TestViewController。
第三步:注册CatchCrash异常处理方法,在Appdelegate写下如下代码:
1. #import "AppDelegate.h"
2. #import "CatchCrash.h"
3. #import "TestViewController.h"
4. @implementation AppDelegate
5. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
6. {
7. self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
8. // Override point for customization after application launch.
9. //注册消息处理函数的处理方法
10. NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
11. testVc = [[TestViewController alloc] init];
12. self.window.rootViewController = testVc;
13. self.window.backgroundColor = [UIColor whiteColor];
14. [self.window makeKeyAndVisible];
15. return YES;
16. }
第四部:在TestViewController的Xib上面添加一个按钮并给其添加一个单击事件,TestViewController.m文件中有如下代码:
1. #import "TestViewController.h"
2. @interface TestViewController ()
3. @end
4.
5. @implementation TestViewController
6. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
7. {
8. self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
9. if (self) {
10. // Custom initialization
11. }
12. return self;
13. }
14.
15. - (void)viewDidLoad
16. {
17. [super viewDidLoad];
18. // Do any additional setup after loading the view from its nib.
19. }
20.
21. - (void)didReceiveMemoryWarning
22. {
23. [super didReceiveMemoryWarning];
24. // Dispose of any resources that can be recreated.
25. }
26.
27. #pragma mark - 单击事件
28. - (IBAction)crashTapped:(id)sender
29. {
30. //常见异常1---不存在方法引用
31. // [self performSelector:@selector(thisMthodDoesNotExist) withObject:nil];
32. //常见异常2---键值对引用nil
33. // [[NSMutableDictionary dictionary] setObject:nil forKey:@"nil"];
34. //常见异常3---数组越界
35. [[NSArray array] objectAtIndex:1];
36. //常见异常4---memory warning 级别3以上
37. // [self performSelector:@selector(killMemory) withObject:nil];
38. //其他大家去想吧
39. }
40.
41. #pragma mark - custom method
42. - (void) killMemory
43. {
44. i = 0; i < 300; i ++)
45. {
46. tmpLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 200)];
47. tmpLabel.layer.masksToBounds = YES;
48. tmpLabel.layer.cornerRadius = 10;
49. tmpLabel.backgroundColor = [UIColor redColor];
50. [self.view addSubview:tmpLabel];
51. }
52. }
53. @end
运行代码:可以看到闪退,导出error日志,我们可以看到:
1. Exception reason:NSRangeException
2. <span style="color:#FF0000;">Exception name:*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds for empty array</span>
3. Exception stack:(
4. <redacted> + 154
5. 1 libobjc.A.dylib 0x39b66ccf objc_exception_throw + 38
6. <redacted> + 176
7. <span style="color:#FF0000;"> 3 TestCrash 0x000e8077 -[TestViewController crashTapped:] + 126</span>
8. <redacted> + 90
9. <redacted> + 30
10. <redacted> + 44
11. <redacted> + 374
12. <redacted> + 590
13. <redacted> + 528
14. <redacted> + 758
15. <redacted> + 196
16. <redacted> + 7102
17. <redacted> + 14
18. <redacted> + 206
19. <redacted> + 622
20. 16 CoreFoundation 0x2f221f0f CFRunLoopRunSpecific + 522
21. 17 CoreFoundation 0x2f221cf3 CFRunLoopRunInMode + 106
22. 18 GraphicsServices 0x3417a663 GSEventRunModal + 138
23. 19 UIKit 0x31b6d16d UIApplicationMain + 1136
24. 20 TestCrash 0x000e810d main + 116
25. <redacted> + 2
26. )