关于异常处理的使用的格式基本就是:程序员
@try { } @catch (NSException *exception) { } @finally { }
经过这段时间对异常处理相关知识的整理,我以为须要掌握如下几个方面的内容:数组
1 要会建立NSException对象,而且会使用@throw抛出异常安全
2 了解异常处理的做用服务器
使用@try进行异常处理,一开始会有相似下面两个问题弄不明白:app
1 既然异常发生了,程序必定会退出,那还须要@final逻辑干吗,程序退出了一切都从新开始不就好了框架
2 异常发生后,而后判断是属于哪一种异常,使用@catch分别处理的意图是什么呢优化
举个简单的例子,对数组越界访问(好比数组总共3个元素,取第4个元素就会产生异常)spa
- (void)test { NSString *name = [self queryValue]; NSLog(@">>>>>>>>>%@", name); if (!name) { NSLog(@">>>>>>>>>通知服务器取值失败"); } else { NSLog(@">>>>>>>>>通知服务器取值成功"); } } - (NSString *)queryValue { NSArray *arr = @[@"111", @"222", @"333"]; NSString *string = [arr objectAtIndex:3]; return string; }
控制台打印的信息:code
2021-08-08 23:35:12.956564+0800 OCTestLine[22690:1921426] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** __boundsFail: index 3 beyond bounds [0 .. 2]' *** First throw call stack: ( 0 CoreFoundation 0x00007fff2dd5ff53 __exceptionPreprocess + 250 1 libobjc.A.dylib 0x00007fff63e25835 objc_exception_throw + 48 2 CoreFoundation 0x00007fff2de22d3a _CFThrowFormattedException + 202 3 CoreFoundation 0x00007fff2de2a203 -[__NSArrayI getObjects:range:].cold.1 + 0 4 CoreFoundation 0x00007fff2dcbd061 -[__NSSingleObjectSetI member:] + 0 5 OCTestLine 0x0000000100000d97 -[PersonClass queryValue] + 135 6 OCTestLine 0x0000000100000c9c -[PersonClass test] + 44 7 OCTestLine 0x0000000100000c47 main + 87 8 libdyld.dylib 0x00007fff651882e5 start + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)
关于这种越界取值的状况,程序会直接抛出异常,抛出异常的结果就是程序crash(崩溃),这在程序开发过程当中相对于“错误”,“异常”致使crash更容易定位bug,这样直截了当地crash的确也没什么,定位bug、修改代码、从新运行就好了,所以在软件开发过程当中,“异常处理”的确没什么用。可是若是有如下需求呢?orm
1 程序闪退以前,我想把这个“异常”信息记录下来,或者记录在本地,或者上传记录在服务器上,方便后期修复优化代码;
2 程序闪退以前,我想把一些“操做”作完,以确保整个系统的安全性;
这样的需求并不过度,好比用户下载了已经发布的版本,使用过程当中出现了闪退,确定是须要进行crash统计的,方便程序员定位问题,腾讯Bugly就是基于此需求开发的框架。
另外,使用异常处理有个现实状况是,当App出现异常闪退了,可是并无真正的“杀死”进程,这个时候是能够继续使用该App的进程继续作其余操做的(好比上传异常信息到服务器)。
{ NSString *name; } - (void)test { @try { name = [self queryValue]; NSLog(@">>>>>>>>>%@", name); } @catch (NSException *exception) { NSLog(@">>>>>>>>>%@", exception); for (int i = 1; i < 11; i++) { sleep(1); NSLog(@">>>>>>>>>将错误信息上传服务器进度:%d%%", i*10); } } @finally { for (int i = 10; i > 0; i--) { sleep(1); NSLog(@">>>>>>>>>退出程序倒计时:%d", i); } if (!name) { NSLog(@">>>>>>>>>通知服务器取值失败"); } else { NSLog(@">>>>>>>>>通知服务器取值成功"); } } } - (NSString *)queryValue { NSArray *arr = @[@"111", @"222", @"333"]; NSString *string = [arr objectAtIndex:3]; return string; }
在控制台的打印结果以下:
2021-08-09 00:00:47.686273+0800 OCTestLine[22920:1933899] >>>>>>>>>*** __boundsFail: index 3 beyond bounds [0 .. 2] 2021-08-09 00:00:48.688200+0800 OCTestLine[22920:1933899] >>>>>>>>>将错误信息上传服务器进度:10% 2021-08-09 00:00:49.693500+0800 OCTestLine[22920:1933899] >>>>>>>>>将错误信息上传服务器进度:20% 2021-08-09 00:00:50.698861+0800 OCTestLine[22920:1933899] >>>>>>>>>将错误信息上传服务器进度:30% 2021-08-09 00:00:51.704219+0800 OCTestLine[22920:1933899] >>>>>>>>>将错误信息上传服务器进度:40% 2021-08-09 00:00:52.709532+0800 OCTestLine[22920:1933899] >>>>>>>>>将错误信息上传服务器进度:50% 2021-08-09 00:00:53.714876+0800 OCTestLine[22920:1933899] >>>>>>>>>将错误信息上传服务器进度:60% 2021-08-09 00:00:54.720185+0800 OCTestLine[22920:1933899] >>>>>>>>>将错误信息上传服务器进度:70% 2021-08-09 00:00:55.725510+0800 OCTestLine[22920:1933899] >>>>>>>>>将错误信息上传服务器进度:80% 2021-08-09 00:00:56.726721+0800 OCTestLine[22920:1933899] >>>>>>>>>将错误信息上传服务器进度:90% 2021-08-09 00:00:57.732028+0800 OCTestLine[22920:1933899] >>>>>>>>>将错误信息上传服务器进度:100% 2021-08-09 00:00:58.737385+0800 OCTestLine[22920:1933899] >>>>>>>>>退出程序倒计时:10 2021-08-09 00:00:59.741825+0800 OCTestLine[22920:1933899] >>>>>>>>>退出程序倒计时:9 2021-08-09 00:01:00.747129+0800 OCTestLine[22920:1933899] >>>>>>>>>退出程序倒计时:8 2021-08-09 00:01:01.752443+0800 OCTestLine[22920:1933899] >>>>>>>>>退出程序倒计时:7 2021-08-09 00:01:02.757756+0800 OCTestLine[22920:1933899] >>>>>>>>>退出程序倒计时:6 2021-08-09 00:01:03.763067+0800 OCTestLine[22920:1933899] >>>>>>>>>退出程序倒计时:5 2021-08-09 00:01:04.768387+0800 OCTestLine[22920:1933899] >>>>>>>>>退出程序倒计时:4 2021-08-09 00:01:05.773704+0800 OCTestLine[22920:1933899] >>>>>>>>>退出程序倒计时:3 2021-08-09 00:01:06.774743+0800 OCTestLine[22920:1933899] >>>>>>>>>退出程序倒计时:2 2021-08-09 00:01:07.780073+0800 OCTestLine[22920:1933899] >>>>>>>>>退出程序倒计时:1 2021-08-09 00:01:07.780251+0800 OCTestLine[22920:1933899] >>>>>>>>>通知服务器取值失败 Program ended with exit code: 0
关于控制台打印的信息,有两点说明:
1 仔细看打印的时间,能够知道,异常发生后,app闪退后,后台进程并无退出,在用户经过“多任务”进行删除app以前,依然能够运行代码作不少事;
2 使用@try正常处理异常,程序是属于正常退出的,“Program ended with exit code:0”。