デバッグまたはリリースで NSLog 出力を表示しないように設定できる特定のフラグはありますか?
ありがとう。
Xcodeでは、特定のビルド構成のマクロを定義できます。たとえば、ここではDEBUG
デバッグビルド用に定義しましたが、リリースビルド用には何も定義していません。
次に、これをコードで使用するには、NSLog(...)
ステートメントをラップします(または、マクロの使用を選択した場合は、update:darrenのメソッドはこの手法で非常に優れています)。
#ifdef DEBUG
NSLog(...);
#endif
リリース構成のみのロジックにも同じメカニズムを使用します。
この機能は、さまざまな数のビルド構成がある場合に使用できます。また、さまざまなビルド構成に対してさまざまなレベルの機能を有効/無効にする場合は、複数のマクロを定義できます。
1つのオプションは、NSLogの代わりにマクロを使用することです(この時点で変更が簡単な場合)。私はこれらの人が使用するプレフィックスヘッダーファイルが好きです:
http://www.cimgf.com/2010/05/02/my-current-prefix-pch-file/
基本的に、それらのロギング機能は次のとおりです。
#ifdef DEBUG
#define DLog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])
#else
#define DLog(...) do { } while (0)
#endif
したがって、DEBUGビルドを使用していない場合、ロギングマクロはノーオペレーションになります。
一般に、ログを「コンパイル」するために、独自のマクロ(DebugLogなど)を作成します。
#undef DebugLog
#ifdef DEBUG_MODE
#define DebugLog( s, ... ) NSLog( @"%@", [NSString stringWithFormat:(s), ##__VA_ARGS] )
#else
#define DebugLog( s, ... )
#endif
新しい Xcode プロジェクトのデフォルト フラグはDEBUG
、デバッグ用であり、リリース用ではありません。したがって、次のようNSLog
に Release で非表示にします。
#ifndef DEBUG
# define NSLog(...)
# define NSLogv(...)
#endif
または、かなりカスタムのログも必要な場合 (#ifdef
シンプルではないため、ここでは使用しません#elifdef
):
#if DEBUG
# define NSLog(format, ...) NSLog((@"%s " format), __PRETTY_FUNCTION__, ##__VA_ARGS__)
# define NSLogv(format, ...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [[NSString alloc] initWithFormat:format arguments:__VA_ARGS__])
#elif ADHOC
// default logs
#else// Release
# define NSLog(...)
# define NSLogv(...)
#endif
これらのマクロをオーバーライドして、時々何かをログに記録したい場合は、次を使用できます。
(NSLog)(@"This log is always visible!");
さて、それらもどのように非表示にしますか?#define NSLog NoLog
のような空の実装を持つ extern 関数として NoLog を定義する必要がありますvoid NoLog(NSString *format, ...) {}
。しかし、完全に使用するのを避け(NSLog)
、代わりに LogLevel 列挙型の関数を使用する方がクリーンになる可能性があります。
typedef NS_ENUM(NSUInteger, LogLevel) {
LogLevelRelease,
LogLevelAdHoc,
LogLevelDeveloper,
};
void CustomLog(LogLevel level, NSString *format, ...) {
#if !DEBUG
if (LogLevel == LogLevelDeveloper)
return;
#if !ADHOC
if (LogLevel == LogLevelAdHoc)
return;
#endif
#endif
va_list ap;
va_start (ap, format);
NSLogv(format, ap);
va_end (ap);
}
この CustomLog の欠点は、Release でも引数が常に評価されることです。したがって、最適なソリューションは複数のマクロです。
#define NSLog(format, ...) NSLog((@"%s " format), __PRETTY_FUNCTION__, ##__VA_ARGS__)
#if DEBUG
# define DebugLog(...) NSLog(__VA_ARGS__)
# define AdHocLog(...) NSLog(__VA_ARGS__)
# define ReleaseLog(...) NSLog(__VA_ARGS__)
#elif ADHOC
# define DebugLog(...)
# define AdHocLog(...) NSLog(__VA_ARGS__)
# define ReleaseLog(...) NSLog(__VA_ARGS__)
#else// Release
# define NSLogv(...)
# define DebugLog(...)
# define AdHocLog(...)
# define ReleaseLog(...) NSLog(__VA_ARGS__)
#endif
このマクロを使用してデバッグ モードを確認します
#ifdef DEBUG
//NSLog(@"XYZ");
#endif
上記の NSLog はリリース モードでは出力されません
プリコンパイル済みヘッダー (.pch) でマクロを定義して、NSLog を無効にすることができます。
#ifdef RELEASE
# define NSLog(...)
#endif
これにより、リリース ビルドで NSLog が無効になります。
このb / cを追加すると、これらのアプローチのいくつかで(プロジェクトの設定によっては)発生する可能性のある警告に対処する回答はないようです。
これは、警告を表示せずに NSLog を抑制する唯一の方法です。それ以外の場合は、使用する設定で大量の情報が得られます (未使用の変数について警告します)。
#undef NSLog
#define NSLog(fmt, ...) if (0) { printf("%s", [[NSString stringWithFormat:fmt, ##__VA_ARGS__] UTF8String]); }
あとは、リリース ビルドに使用する pch ファイルや、ログを抑制したい場所にそれを配置するだけです。
変数を「使用」する方法の例については、@Hot Licks の功績によるものです。