例外処理の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");
}
参考