2012-03-21 21 views
3

私は自分のMacアプリケーションで例外をキャッチしてカスタムログファイルに記録できるようにしようとしています。未知の例外ハンドラが呼び出されていない

void uncaughtExceptionHandler(NSException *exception) { 
    NSLog(@"It Works!"); 
} 

そして、私はこのように私の-applicationDidFinishLaunching:方法でそれを設定しています:私はこのような例外ハンドラを実装しています

NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler); 

は、その後、私はこのようにそれをテストするために、例外が発生:

[[NSArray arrayWithObject:@"object"] objectAtIndex:1]; 

例外はコンソールに記録されますが、例外ハンドラは呼び出されていません。

アイデア?

答えて

4

解決策は、ExceptionHandlingフレームワークを使用することです。ここで私はそれをやった方法は次のとおりです。

[[NSExceptionHandler defaultExceptionHandler] setExceptionHandlingMask:NSLogAndHandleEveryExceptionMask]; 
[[NSExceptionHandler defaultExceptionHandler] setDelegate:self]; 

-applicationDidFinishLaunching:ではその後、私のApp Delegateクラスで私は2つのデリゲートメソッドを実装し、

- (BOOL)exceptionHandler:(NSExceptionHandler *)sender shouldLogException:(NSException *)exception mask:(NSUInteger)aMask 
- (BOOL)exceptionHandler:(NSExceptionHandler *)sender shouldHandleException:(NSException *)exception mask:(NSUInteger)aMask 

今、私はすべての例外をキャッチすることができます!

2

AppKitには、例外を最初にキャッチしているメインスレッド上に独自の高レベル例外ハンドラがあります。 NSApplicationをサブクラス化し、-reportException:を上書きして何かを行うことができます。

あなたの例外ハンドラは、まだ他のスレッドで呼び出される可能性があります。

参照:Tim Wood's message on macosx-dev back in 1999

+0

私はそれを試みましたが、私はまだ例外をキャッチしていません。 '-reportException:'は決して呼び出されません。 '-applicationDidFinishLaunching:'で例外が発生した場合は、呼び出さないでください。メインスレッドで実行されていませんか? – edc1591

+0

はい、 '-applicationDidFinishLaunching:'はメインスレッドで呼び出されます。 'NSApplication'サブクラスが使用されていますか?あなたは 'Info.plist'の中でクラス名をキー' NSPrincipalClass'の下に指定する必要があります。 –

+0

はい、私は確信しています。 '[NSApp class];'は私のサブクラスを返します。 – edc1591

関連する問題