8

assert() を多用した iPhone アプリ (Xcode、Objective-C++、およびデバイス シミュレーター) をデバッグしています。場合によっては、アサートの失敗により、期待どおりにデバッガーに侵入するのではなく、アプリが終了するだけでした。

私は次のような独自のアサートを実装することで回避策を作成しました。

#define AssertLite(b) if(!(b)) {asm {int 3}}

(毛羽立ち省略)ですが、これに遭遇した人はいるのだろうか。いつ壊れていつ終了するかについてのパターンを特定できませんでした。コードはスレッド化されていません。行うことはすべて、イベント ハンドラーで行われます。

なぜこれが起こるのですか?どうすればバニラ assert() を条件付きブレークポイントのように動作させることができますか?

4

4 に答える 4

15

まず、iPhone アプリで作業しているので、通常の BSD アサート関数の代わりに NSAssert() を使用する必要があります。

例えばNSAssert(the_object, @"NIL object encountered");

NSAssert マクロはNSInternalInconsistencyException、アサーションが失敗した場合、Objective-C 例外 ( ) をスローします。

目標は例外で中断することなので、次のステップは Xcode デバッガーを Objective-C 例外で中断させることです。これはおそらくどうでもいいことです。

[ブレークポイント] ウィンドウ ([実行] -> [表示] -> [ブレークポイント] メニュー項目) で、[シンボルをダブルクリック] と表示されている場所をクリックして、シンボルを入力します。-[NSException raise]

最後に注意すべきことは、リリース ビルドで NSAssert がコンパイルされないことです。つまり、アプリケーションで例外を処理する準備をするか、リリース ビルドでコンパイル アウトする独自のマクロを作成する必要があります。

実行時コードでアサーションをコンパイルするために使用するマクロを次に示します (その後、コードで NSAssert の代わりに HMAssert を使用することに注意してください)。

#ifdef DEBUG
#   define HMAssert(A,B) NSAssert(A,B)
#else
#   define HMAssert(A,B)
#endif

これには、DEBUG プリプロセッサ マクロを定義する必要があります。設定方法は次のとおりです。

  1. Xcode でプロジェクトを右クリックします。これは、プロジェクト ファイルがリストされている左側のパネルの一番上の項目になります。
  2. 表示されるコンテキスト メニューから [情報を見る] を選択します。
  3. 「ビルド」タブに移動します。
  4. 「構成」が「デバッグ」に設定されていることを確認します。
  5. 「GCC 4.2 - Preprocessing」の下の「Preprocessor Macros」の横のフィールドに DEBUG と入力します。
于 2010-01-05T00:48:52.493 に答える
4

まず、Breakpoint Navigator で [Add Exception Breakpoint...] を実行すると (⌘6)、デバッガーは NSAssert の失敗で停​​止し、スタックを見て何が問題なのかを理解できるようになります。

標準の NSAssert を使用する必要があります。正しく使用すれば、手動で作成する必要があるものは多くありません。Mike が言及しているものはすべて、デフォルトの NSAssert 実装に似ています。

アサーションを無効にするには、プリコンパイル済みヘッダーに NS_BLOCK_ASSERTIONS を設定してリリース構成を実行する必要があります (Mike の手順に従います)。その理由についてさらに詳しい情報が必要な場合は、http: //myok12.wordpress.com/2010/10/10/to-use-or-not-to-use-assertions/を確認してください。

于 2010-11-24T02:52:09.613 に答える
0

assert() 呼び出しとは異なる動作が 1 回見られました。これは、コンパイラがビルド プロセスのさまざまな部分でさまざまなマクロ定義を取得したことが原因でした。

インクルードパスがまっすぐになると、それらはすべて同じように機能しました。

于 2013-02-14T07:57:27.193 に答える
0

Xcode 4 および新しい iOS では、NSAssert は実際にはパラメーターの可変リストを受け取る場合があります。これは、アサートと一緒にいくつかの値をログに記録するのに役立つ場合があります。コンパイルアウトアサート (上記の Mike による回答を参照) は、次のように定義できます。

#ifdef DEBUG
#   define DAssert(A, B, ...) NSAssert(A, B, ##__VA_ARGS__);
#else
#   define DAssert(...);
#endif

また、Run → Show → Breakpoints メニュー項目はなくなりました。この投稿を参照して、上記で定義したアサートで中断するように Xcode 4 を設定してください。

于 2012-04-23T13:50:39.617 に答える