NSException ... @try @catch @finally (异常处理)

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的方案,记得分享)

猜你喜欢

转载自blog.csdn.net/lovehalok/article/details/80111949