2011-12-13 4 views
6

私の友人はNSDictionaryと何か変わった動作を発見しました。なぜそれが起こるのか不思議です。次のコードを考えてみましょう:このObjective Cコールがハングアップしているように見えるのはなぜですか?

NSDictionary *dict = [[NSDictionary alloc] init]; 

// Oops, we can't mutate an NSDictionary 
[dict setObject:[[NSNull alloc] init] forKey:@"test"]; 
NSLog(@"Set"); 

コードは「『NSDictionaryのは、』 『:forKey:のsetObject』に応答しないこと」というコンパイル時に警告を生成します。それはすべてが順調と良いことだ、とあなたはとにかくそれを実行する場合は、コンソールでこの出力を取得します:

- [__ NSCFDictionaryのsetObject:forKey:]:不変オブジェクトに送られた変異法

もう一度、あなたは何が起こると思いますか。しかし、現時点ではのアプリケーションは、キャッチされない例外のためにをクラッシュせず、終了しません。 setObject:forKey:メソッドは単に返されず、アプリケーションはハングしているように見えます。次のNSLogは決して実行されません。 GDBを使用してメソッドをステップインしたり、メソッドに入れようとすると、デバッグは終了するようですが、明示的なエラーメッセージは表示されません。アプリケーションは引き続き実行されますが、デバッガは実行中のコードがどこに「スタックしている」かのヒントを提供しません。

ここでは何が起こっていますか?この場合、アプリは実際に何をしていますか?なぜ、NSInternalInconsistencyExceptionやそのようなものでクラッシュしないのですか?

編集は:求めている人のために、私は、OS Xのライオン(10.7.2)にXCodeの4.1を実行していると建物 "のApple LLVMコンパイラ2.1。"私はあなたがXCode 4で新しいCocoaプロジェクトを使うときのデフォルト設定をすべて使用しています。私はプログラムをデバッグするかどうかに関係なく、同じ非クラッシュ動作を経験します。デバッグビルディングからリリースビルディングに変更することで違いはありません。私はFinderで.appファイルを手動で見つけて、それをダブルクリックしてXCodeの外で実行することさえできますが、それでもクラッシュはありません。

+1

デバッガでは実行しないでください。私はそれがハードクラッシュ賭ける。私は、デバッガ環境は、特に例外の周りの実行時環境にいくつかの予期しない影響を与えることができ、それらをヒットしたときに何が起こるかを見つける。 –

+2

例外がスローされると、例外の後に次の行ではなく、例外をキャッチして制御が再開されます。あなたの例では、デバッガまたはランタイムのいずれかの腸が例外を "捕まえ"ました。いずれにしても、-setObject:forKey:が例外をスローした後にNSLogが発生することは期待できません。 –

+0

@VincentGable:プログラムがクラッシュしたら同意しました。私はNSLogが呼び出されなかったことに少しも驚かないでしょう。私が驚いたことは、それがクラッシュしたり次の行に進むことがないことです。それは、どちらか一方をすべきだと思われます。質問した人には、私が実行している環境に関するいくつかの追加の詳細を質問に更新しました。 –

答えて

1

例外は、AppKitプログラムをクラッシュさせません。 NSApplicationは、あなたのコードにはない例外をキャッチするデフォルトの例外ハンドラをインストールします。その後、あなたは通常のようにrunloopに戻ります。

多くのアプリでこの現象が発生します。これは、不可解な空白のビュー/ウィンドウの一般的な原因です。ビューが描画を終了する前に例外が発生すると、ビューは空白になりますが、アプリケーションはクラッシュしません。例外は、意図的にクラッシュするデフォルト例外ハンドラを変更した場合にのみクラッシュを引き起こします。

+0

ありがとう、これは主に私の答えです質問。私がまだ混乱していることの1つは、例外がキャッチされた後にアプリケーションがメインイベントループに戻るのを見ることができない理由です。または、それは別のスレッドで発生しますか?私はAppKitの内部の仕組みに精通しているわけではありません。 –

関連する問題