6

私が何かを書くとき、労力の半分は、明確で簡潔なデバッグ出力、またはデバッグが必要なときに有効/無効にできる機能を追加することに費やされる傾向があります。

デバッグ機能の例はダウンローダ クラスです。#define をオンにすると、ファイルをダウンロードするふりをして、既に持っているファイルを単純に返すことができます。そうすれば、毎回ネットワークがファイルを物理的に取得するのを待つことなく、ユーザーがファイルをダウンロードしたときに何が起こるかをテストできます。これは素晴らしい機能ですが、#ifdefs を使用するとコードが煩雑になります。

私は最終的に次#defineのような一連の s になります

// #define DEBUG_FOOMODULE_FOO
// #define DEBUG_BARMODULE_THINGAMAJIG
// ...

私が見たいもののコメントが外されています。コード自体は次のようになります

- (void)something
{
    #ifdef DEBUG_FOOMODULE_FOO
    DebugLog(@"something [x = %@]", x);
    #endif
    // ...
    #ifdef DEBUG_FOOMODULE_MOO
    // etc
}

これは、コードの作成/保守には最適ですが、コードの外観には何の影響もありません。

とにかく、人々はどのようにして簡単にオンザフライの長期デバッグ「もの」を書くのでしょうか?

注:ここでは NSLogging について話しているだけではありません。上記のふりダウンロードのようなものについても話しているのです。

4

3 に答える 3

2

独自のライブラリを作成する前にいくつかのライブラリを読み、マクロ + C 関数 ( NSLogger ) またはマクロ + シングルトン ( GTMLoggerCocoa Lumberjack )の 2 つのアプローチを見ました。

ここでは、マクロ + シングルトンを使用して単純な実装を記述しました。私は実行時にこれを行います:

[Logger singleton].logThreshold = kDebug;
trace(@"hi %@",@"world); // won't show
debug(@"hi %@",@"world);

ログレベルの代わりにパッケージに対して同じことを行うことができます。消したい場合は、#defines を変更します。関連するコードは次のとおりです。

#define trace(args...) [[Logger singleton] debugWithLevel:kTrace line:__LINE__ funcName:__PRETTY_FUNCTION__ message:args];

if (level>=logThreshold){
  // ...
} 

Lumberjack をより洗練されたものにしたい場合は、一部のクラスのログ記録を切り替えるレジスタ クラス機能があります。

于 2011-07-20T13:35:28.890 に答える
1

2 つの関数を用意し、実行時またはコンパイル時にそれらを適切に選択することは、私にとってはクリーンなアプローチのように思えます。これにより、実装が異なることを除いて、同じ機能を持つdownload.c1 つのファイルを持つことが可能になります。download_debug.c次に、-DDEBUG を使用してビルドしているかどうかにかかわらず、適切なものにリンクします。

それ以外の場合、関数ポインターを使用すると、実行時の選択関数にも機能します。

関数全体にデバッグコードを散在させることを主張する場合、あなたはかなり混乱するように自分自身を設定しています:)しかし、もちろん、これらのスニペットを別々の関数に分割してから、上記を実行できます(または、 DLog の例)。

于 2011-07-29T12:39:26.197 に答える
0

あなたのケースでは、別々のフラグに基づいてすべて条件付きでコンパイルする別々のロギング マクロ、たとえばMooLogと を使用できます。FooLog

#ifdef DEBUG_FOO
#   define FooLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#   define FooLog(...)
#endif

#ifdef DEBUG_MOO
#   define MooLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#   define MooLog(...)
#endif

どこでも複雑なロジックは次のようになります。

- (void)something
{
    // This only gets logged if the "DEBUG_FOO" flag is set.
    FooLog(@"something [x = %@]", x);
    // This only gets logged if the "DEBUG_MOO" flag is set.
    MooLog(@"Something else [y = %@]", y);
}
于 2011-07-20T12:07:16.767 に答える