NSException
情景
Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ’ -[__NSArrayM insertObject:atIndex:]: object cannot be nil’
* First throw call stack:…(省略)
上面这端打印信息,对于ios开发者来说,是再熟悉不过了!但很少思考,是谁抛出这些异常,帮助我们定位问题?我们能利用它搞点什么事情吗?
是谁
它就是NSException!
看看官方文档对NSException描述(这里只截取部分)。
An object that represents a special condition that interrupts the normal flow of program execution.
去掉第一个that后的限定词,“An object that interrupts the normal flow of program execution.”,英语不好,我这边直接理解为“一个可以中断程序执行的对象”,
加上去掉的that条件:“在特定条件下,一个可以中断程序执行的对象”,
瞬间感觉厉害了,可以中断程序!~~~~
基本使用
1.简单调用
- (void)viewDidLoad {
[super viewDidLoad];
NSDictionary * exceptionDic = [NSDictionary dictionary];
NSException * exception = [NSException exceptionWithName:@"异常信息类性" reason:@"抛出异常原因" userInfo:exceptionDic];
@throw exception;
}
打印:
Terminating app due to uncaught exception '异常信息类性', reason: '抛出异常原因'
*** First throw call stack:....(省略)
2.给数组追加nil
- (void)viewDidLoad {
[super viewDidLoad];
NSString * string = nil;
NSMutableArray * mutableArray = [NSMutableArray array];
@try{
[mutableArray addObject:string];
}
@catch(NSException * exception){
NSLog(@" \n异常name = %@ \n 异常reason = %@" ,exception.name, exception.reason);
}
@finally{
NSLog(@"最后");
}
}
打印:
异常name = NSInvalidArgumentException
异常reason = *** -[__NSArrayM insertObject:atIndex:]: object cannot be nil
最后
注:在catch里面依然可以使用@throw exception让系统抛出异常来!
3.在数组category分类里面运用NSException捕获异常。
+ (void)load {
//注意数组类簇,创建出来的数组本质上是其中的一种。方法交换需要将这几种情况考虑全! <__NSArray0 、__NSSingleObjectArrayI 、__NSArrayI> 详细可以了解''Clusters''
Class arrayClass = NSClassFromString(@"__NSArrayM");
Method m1 = class_getInstanceMethod(arrayClass, @selector(addObject:));
Method m2 = class_getInstanceMethod(arrayClass, @selector(m_AddObject:));
method_exchangeImplementations(m1, m2);
}
- (void) m_AddObject:(id)anObject {
@try {
[self m_AddObject:anObject];
}
@catch (NSException *exception) {
NSLog(@"异常名称:%@ 异常原因:%@",exception.name, exception.reason);
}
@finally {
//这里也可以进行相应的操作
}
}
获取APP崩溃日志
项目上线后,如果需要收集异常信息,如何做?
第一种,选择第三方,如bugly 等(不是打广告);
第二种,自己处理。在程序崩溃前保存错误信息,在下次APP启动时,报告给我们自己的服务器。
操作如下:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSSetUncaughtExceptionHandler(&MK_ExceptionHandler);
return YES;
}
void MK_ExceptionHandler(NSException *exception){
NSArray *symbols = [exception callStackSymbols]; //堆栈信息
NSString *reason = [exception reason];
NSString *name = [exception name];
NSLog(@"%@-%@-%@",symbols,reason,name);
/*在这里将捕获的异常保存起来,如写入沙河,下次APP启动后再上传给服务器*/
}
(分享仅供参考,还有更牛x的方案,记得分享)