注目の記事

iOSアプリ開発で例外の発生した場所を特定する

2012.10.02

iOSアプリを開発していて、例外が発生してアプリがクラッシュしてしまうことがしばしばあります。
Xcodeでは、クラッシュ時に得られる情報が少ないので、原因究明に時間がかかってしまいます。
そんなときは、「NSSetUncaughtExceptionHandler」を使用すると便利です。

まず、試しに、よくある例外をわざと発生させてみます。

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // ここで、わざと例外を発生させてみます。
    [[NSArray array] objectAtIndex:0];
}

実行すると以下のようになります。

「UIApplicationMain」で止まってしまって、状況がよくわかりません。
「NSRangeException」が発生したことくらいはわかりますが、もう少し情報が欲しいところです。

そこで、「NSSetUncaughtExceptionHandler」を使用して、もう少し詳しい情報を取得してみます。
使い方は簡単で、「NSSetUncaughtExceptionHandler」の引数に、例外発生時に処理したい関数を渡すだけです。

「AppDelegate.m」内を少し修正します。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
    return YES;
}

void uncaughtExceptionHandler(NSException *exception)
{
    // ここで、例外発生時の情報を出力します。
    NSLog(@"%@", exception.name);
    NSLog(@"%@", exception.reason);
    NSLog(@"%@", exception.callStackSymbols);
}

そして、実行してみます。

すると、スタックのログを取ることができ、どんな流れで処理が行われたのかがわかります。
今回の場合では赤枠内を見てみると、
ViewControllerの「viewDidLoad」から、NSArrayの「objectAtIndex:」が呼ばれた後で、例外が発生しているのがわかります。

このように「NSSetUncaughtExceptionHandler」を使用すると、例外の発生した場所を簡単に特定できます。