LoginSignup
52
52

More than 5 years have passed since last update.

Objective-C 例外処理(try-catch-finally)

Last updated at Posted at 2013-03-18

例外処理のtry-catch-finallyの流れの確認です。

サンプルコード

NSMutableStringで範囲外の例外を起こします。

Test.m
- (void)test
{    
    NSMutableString *str = [@"01234" mutableCopy];

    /* 常に実行される */
    @try {
        // 範囲外の例外(NSRangeException)を起こす
        [str replaceCharactersInRange:NSMakeRange(0, 6) withString:@"x"];
        NSLog(@"%@", str); // 01234 (リプレースされないでそのまま)
     }

    /* 例外が起きると実行される */
    @catch (NSException *exception) {
        NSLog(@"[ERROR]\nstr[%@]\nexception[%@]", str, exception);

        /* 本来の例外処理に投げる (@throwしなければクラッシュされない。@finallyが実行されstrは元の@"01234"の値のまま) */
        @throw exception;
        /* @finallyが実行された後に本来の例外ログが表示されクラッシュ

            *** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFString replaceCharactersInRange:withString:]: Range or index out of bounds'
            *** First throw call stack:
            (0x1c8d012 0x10cae7e 0x1c8cdeb 0x1ce94ca 0x2f61 0x10de705 0x15920 0x158b8 0xd6671 0xd6bcf 0xd5d38 0x4533f 0x45552 0x233aa 0x14cf8 0x1be8df9 0x1be8ad0 0x1c02bf5 0x1c02962 0x1c33bb6 0x1c32f44 0x1c32e1b 0x1be77e3 0x1be7668 0x1265c 0x2b4d 0x2a75)
            libc++abi.dylib: terminate called throwing an exception

         */
    }

    /* 常に実行される */
    @finally {
        NSLog(@"*** finally ***");
    }

    NSLog(@"check"); // 実行されない
}

おまけ

try-catch-finallyは実行コストが高いので、DEBUG時のみ実行したいときは下記のように書けばいいかと思います。

Test.m
- (void)test
{    
    NSMutableString *str = [@"01234" mutableCopy];

    /* 常に実行される */
#if DEBUG
    @try {
#endif
        // 範囲外の例外(NSRangeException)を起こす
        [str replaceCharactersInRange:NSMakeRange(0, 6) withString:@"x"];
        NSLog(@"%@", str); // 01234 (リプレースされないでそのまま)
#if DEBUG
     }
    /* 例外が起きると実行される */
    @catch (NSException *exception) {
        NSLog(@"[ERROR]\nstr[%@]\nexception[%@]", str, exception);

        /* 本来の例外処理に投げる (@throwしなければクラッシュせずに@finallyが実行されstrは元の@"01234"の値のまま) */
        @throw exception;
        /* @finallyが実行された後に本来の例外ログが表示されクラッシュ

            *** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFString replaceCharactersInRange:withString:]: Range or index out of bounds'
            *** First throw call stack:
            (0x1c8d012 0x10cae7e 0x1c8cdeb 0x1ce94ca 0x2f61 0x10de705 0x15920 0x158b8 0xd6671 0xd6bcf 0xd5d38 0x4533f 0x45552 0x233aa 0x14cf8 0x1be8df9 0x1be8ad0 0x1c02bf5 0x1c02962 0x1c33bb6 0x1c32f44 0x1c32e1b 0x1be77e3 0x1be7668 0x1265c 0x2b4d 0x2a75)
            libc++abi.dylib: terminate called throwing an exception

         */
    }
    /* 常に実行される */
    @finally {
        NSLog(@"*** finally ***");
    }
#endif
    NSLog(@"check");
}

参考

52
52
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
52
52