数组越界、空引用、引用未定义方法、内存空间不足等等。


如何获取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文件

  1. #import <Foundation/Foundation.h>  
  2. @interface CatchCrash : NSObject  
  3. void uncaughtExceptionHandler(NSException *exception);   
  4. @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. )