编写高质量代码的52个有效方法

52个有效方法(32) - 编写“异常安全代码”时留意内存管理问

2018-09-07  本文已影响15人  SkyMing一C
异常安全代码
@try {

    // 可能会出现崩溃的代码

}

@catch (NSException *exception) {

    // 捕获到的异常exception

}

@finally {

    // 结果处理
    //无论是否抛出异常,其中的代码都保证会运行,且只运行一次。

}
例子
@try {

    // 1

    [self tryTwo];

}

@catch (NSException *exception) {

    // 2

    NSLog(@"%s\n%@", __FUNCTION__, exception);

//        @throw exception; // 这里不能再抛异常

}

@finally {

    // 3

    NSLog(@"我一定会执行");

}

// 4

// 这里一定会执行

NSLog(@"try");
//tryTwo方法代码
- (void)tryTwo

{

    @try {

        // 5

        NSString *str = @"abc";

        [str substringFromIndex:111]; // 程序到这里会崩

    }

    @catch (NSException *exception) {

        // 6

//        @throw exception; // 抛出异常,即由上一级处理

        // 7

        NSLog(@"%s\n%@", __FUNCTION__, exception);

    }

    @finally {

        // 8

        NSLog(@"tryTwo - 我一定会执行");

    }

    // 9

    // 如果抛出异常,那么这段代码则不会执行

    NSLog(@"如果这里抛出异常,那么这段代码则不会执行");

}
//AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Override point for customization after application launch.

    NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);

    return YES;

}

 

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"]];

 

    /**

     *  把异常崩溃信息发送至开发者邮件

     */

    NSMutableString *mailUrl = [NSMutableString string];

    [mailUrl appendString:@"mailto:test@qq.com"];

    [mailUrl appendString:@"?subject=程序异常崩溃,请配合发送异常报告,谢谢合作!"];

    [mailUrl appendFormat:@"&body=%@", content];

    // 打开地址

    NSString *mailPath = [mailUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:mailPath]];

}
为什么iOS很少使用try catch
要点
  1. 捕获异常时,一定要注意将try块内所创立的对象清理干净。

  2. 在默认情况下,ARC不生成安全处理一次所需的清理代码。开启编译器标志后(-fobjc-arc-exceptions),可生成这种代码,不过会导致应用程序变大,而且会降低运行效率。

上一篇 下一篇

猜你喜欢

热点阅读