iOS 异常处理 崩溃日志收集

在OC用try catch finally捕获异常,把可能出现异常的地方使用,比如访问数组的时候,在用perform系列方法的时候建议加上,可以捕获到找不到方法的异常,不会使程序崩溃。

 @try {
        NSString *a=(NSString *)[NSNullnull];
        if ([aintegerValue]) {
            NSLog(@"%@",[NSNullnull]);
        }else{
            NSLog(@"%@",[NSNullnull]);
        }
        NSLog(@"@try");
    } @catch (NSException *exception) {
        NSLog(@"%@",exception);
    } @finally {
        NSLog(@"@finally");
    }

使用友盟之后如果友盟拦截全局异常的开关打开,友盟就能拦截全局的异常。当然,也可以自己收集这些异常信息,方法就是使用NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);

void UncaughtExceptionHandler(NSException *exception) {
    /**
     *  获取异常崩溃的堆栈信息
     */
    NSArray *callStack = [exception callStackSymbols];
    NSString *reason = [exception reason];
    NSString *name = [exception name];
    NSString *content = [NSString stringWithFormat:@"========异常错误报告========\nname:%@\nreason:\n%@\ncallStackSymbols:\n%@",name,reason,[callStack componentsJoinedByString:@"\n"]];
//一般保存到本地,下次启动的时候上传到服务器,
//清理缓存文件
 

}

UncaughtExceptionHandler是一个函数指针(总和指针函数弄混,在这里备注一下:函数指针是指向函数的指针变量,即本质是一个指针变量;指针函数本质是一个函数。函数返回类型是某一类型的指针),这样就可以在这个c函数里把日志上传到你自己的服务器了。
如果即想让友盟收集崩溃日志,又想往自己的服务器上上传一份的话,怎么做呢?
因为这是一个指针函数,所以,后设置的会覆盖之前设置的,所以需要先获取友盟的函数指针,用变量保存起来,在自己设置的函数里调用友盟的函数就可以了,具体代码如下:

static NSUncaughtExceptionHandler * UMcrashHandler; //用一个静态变量保存友盟的函数
//友盟初始化结束之后,获取友盟的函数
UMcrashHandler =  NSGetUncaughtExceptionHandler();
//设置自己的函数
NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
//在自己的函数里调用友盟的函数
void UncaughtExceptionHandler(NSException *exception) {
    /**
     *  获取异常崩溃的堆栈信息
     */
    NSArray *callStack = [exception callStackSymbols];
    NSString *reason = [exception reason];
    NSString *name = [exception name];
    NSString *content = [NSString stringWithFormat:@"========crash report========\nname:%@\nreason:\n%@\ncallStackSymbols:\n%@",name,reason,[callStack componentsJoinedByString:@"\n"]];
//调用友盟的函数
    if (UMcrashHandler) {
        UMcrashHandler(exception);
    }
}

这样就实现了即调用了友盟的崩溃日志收集,又调用了自己的异常收集,友盟的接口里边也有一个block回调,可以做一些自己的事情,但是这个回调里边没有NSException这个对象,所以如果你想收集崩溃日志到自己的服务器,这个block还不能用。当然,如果只是想在崩溃之后执行一些操作(比如清除缓存或者数据库),还是够用的

//友盟给的回调,没有exception对象
+ (void)setCrashCBBlock:(CallbackBlock)cbBlock;

你可能感兴趣的:(iOS)