iPhone用アプリをリリースするとき、無効にすると NSLog();
するとパフォーマンスが向上しますか?
NSLog()
アプリ全体の数に依存します。NSLog()
実行に時間がかかり、アプリのランタイムにオーバーヘッドが追加されます。とにかく、単純なDEBUGプリプロセッサマクロでパフォーマンスが向上する場合は、無効にする必要があります。
iPhone用アプリをリリースするとき、無効にすると NSLog();
するとパフォーマンスが向上しますか?
NSLog()
アプリ全体の数に依存します。NSLog()
実行に時間がかかり、アプリのランタイムにオーバーヘッドが追加されます。とにかく、単純なDEBUGプリプロセッサマクロでパフォーマンスが向上する場合は、無効にする必要があります。
回答:
これを行う1つの方法は、ビルド設定に移動し、デバッグ構成の下で、「プリプロセッサマクロ」の値に次のような値を追加することです。
DEBUG_MODE=1
これは、デバッグ構成でのみ行い、ベータ版またはリリース版では行わないでください。次に、一般的なヘッダーファイルで次のようなことができます。
#ifdef DEBUG_MODE
#define DLog( s, ... ) NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define DLog( s, ... )
#endif
どこでもNSLog
使用する代わりにDLog
。テストとデバッグを行うと、デバッグメッセージが表示されます。ベータ版または最終リリースをリリースする準備ができると、これらのDLog
行はすべて自動的に空になり、何も出力されません。この方法では、変数の手動設定やNSLogs
必須のコメントはありません。ビルドターゲットを選択すると、それが処理されます。
Xcode 5およびiOS 7のアップデート
注:リリースビルドでprint()ステートメントを削除するXcode 7 / Swift 2.1ソリューションについては、ここで私の答えを見つけてください。
はい、コードを遅くするだけで、リリースバージョンでは何の役にも立たないので、リリースコードからNSLogステートメントを削除する必要があります。幸い、Xcode 5(iOS 7)では、リリースビルドですべてのNSLogステートメントを「自動的に」削除するのは驚くほど簡単です。だからそれをしないのはなぜですか。
最初に行う3つのステップ、次にいくつかの説明
1)Xcodeプロジェクトで、「yourProjectName-prefix.pch」ファイルを見つけます(通常、これはmain.mファイルが置かれている「サポートファイル」グループの下にあります)
2)「.pch」ファイルの最後に次の3行を追加します。
#ifndef DEBUG
#define NSLog(...);
#endif
3)「デバッグ」バージョンと「リリース」バージョンの違いをテストします。これを行う1つの方法は、「スキームの編集」->「アプリ名の実行」->「情報」タブの下で、デバッグとリリースの間のドロップダウンボックスを使用して選択することです。リリースバージョンでは、デバッグコンソールにNSLog出力は表示されません。
これはどのように機能しますか?
まず、プリプロセッサは比較的「ダム」であり、コンパイラが呼び出される前に「テキストの置き換え」として機能することを知っておく必要があります。これは、「#define」を#define
ステートメントに続くものに置き換えます。
#define NSLog(...);
(...)
括弧の間の「何でも」()の略です。;
最後に心も。コンパイラーがこれを最適化するため、これは厳密には必要ありませんが、より「正しい」ため、ここに配置するのが好きです。私たちの後#define
プリプロセッサは「何もない」と交換します、そしてそれはただで始まる、完全なラインを捨てますので、「何も」ありませんNSLog...
までを含みます;
。
定義ステートメントは#ifdef
、#ifndef
(定義されている場合)または(定義されていない場合)を使用して条件付きにすることができます。
ここではと記述します#ifndef DEBUG
。これは、「シンボルDEBUGが定義されていない場合」を意味します。#ifdef
または#ifndef
で「閉じた」ことの必要性#endif
Xcode 5は、ビルドモードが「DEBUG」の場合、デフォルトで「DEBUG」シンボルを定義します。「リリース」では、これは定義されていません。これはプロジェクト設定の[ビルド設定]タブで確認できます-> [Apple LLVM 5.0-前処理]-> [プリプロセッサマクロ]セクションまでスクロールします。シンボル「DEBUG」がリリースビルドに対して定義されていないことがわかります。
最後に、.pchファイルはXcodeによって自動的に作成され、コンパイル時にすべてのソースファイルに自動的に含まれます。つまり、すべてを#define
ソースファイルのそれぞれに挿入するようなものです。
NSLog
ます。
NSLog
何もしないステートメントとして使用しないでください。たとえば、中括弧でif(AllCool) NSLog(@"Cool!Do Nothing!"); else...
ポップしNSLog
ますif(AllCool) {NSLog(@"Cool!Do Nothing!");} else...
上記のほとんどすべての回答が解決策を提案していますが、問題を説明していません。グーグルで検索して、その理由を見つけました。これが私の答えです:
はい、リリースバージョンでNSLogをコメントアウトすると、パフォーマンスが向上します。NSLogはかなり遅いからです。どうして?NSLogは2つのことを行います。1)Apple System Logging(ASL)にログメッセージを書き込みます。2)アプリがxcodeで実行されている場合、stderrにも書き込みます。
主な問題は最初の問題にあります。スレッドセーフを実現するために、NSLogが呼び出されるたびに、ASL機能への接続が開かれます。メッセージを送信し、接続を閉じます。接続操作は非常に高価です。別の理由は、NSLogがログに記録するためのタイムスタンプを取得するためにある程度の時間を費やしていることです。
私の個人的なお気に入りは、可変個のマクロを使用することです。
#ifdef NDEBUG
#define NSLog(...) /* suppress NSLog when in release mode */
#endif
呼びかけないことを賢明にコメントしたすべての人々に加えて NSLog()
本番行わ加えて、私はそれを追加します:
これらのNSLog()
出力文字列はすべて、ストアからアプリをダウンロードし、Xcodeを実行しているMacに接続されたデバイスでアプリを実行するすべてのユーザーに表示されます([オーガナイザー]ウィンドウから)ます。
ログに記録する情報に応じて(特に、アプリがサーバーに接続する場合、認証を行う場合など)、これは深刻なセキュリティ問題になる可能性があります。
print()
が、おそらく同じです。
Xcodeのプロジェクトの現在のデフォルト設定内では、NS_BLOCK_ASSERTIONS
マクロはリリースバージョンとDEBUG=1
デバッグバージョンで1に設定されます。
なので、次の方法がいいです。
// NS_BLOCK_ASSERTIONS is defined by default, as shown in the screenshot above.
// Or, you can define yourself Flags in the `Other C Flags` -> `Release`.
#ifndef NS_BLOCK_ASSERTIONS
#define _DEBUG
#endif
#ifdef _DEBUG
// for debug mode
#define DLog(fmt,...) NSLog(@"%s " fmt, __FUNCTION, ##__VA_ARGS__)
... /// something extra
#else
// for release mode
#define DLog(fmt,...) /* throw it away */
... /// something extra
#endif
すべての良い回答ですが、主にアプリの開発/テスト段階で使用することを検討できるもう1つの小さなトリックがあります。
また、コードを直接制御できない問題を示す可能性のあるメッセージではなく、デバッグコードをオフにするだけの場合は、アプリのリリースコードにも役立ちます。
トリック:
.mファイルの先頭に次の行を含めるだけで、.mファイルごとにNSLogをオフにできます。
#define NSLog(...)
(注:DO NOT、唯一の.mファイルを、この.Hファイルを入れて!)
これは、NSLog()
代わりにプリプロセッサーマクロを展開してコンパイラーを評価させるだけです。マクロは引数を取り除くだけです。
もう一度オンにしたい場合は、いつでも使用できます
#undef NSLog
たとえば、次のようなことを行うことで、特定のメソッドグループを中心としたNSLogの呼び出しを防ぐことができます。
#define NSLog(...)
-(void) myProblematicMethodThatSometimesNeedsDebugging {
...
}
#undef NSLog
pchファイルでこれを#endifの前に書き留めてください
#define NSLog() //
これはどうですか?
#ifndef DEBUG_MODE
fclose(stderr); // the simplest way to disable output from NSLog
#endif
var showDebugLogs = false;
func DLog(format: String, args: CVarArgType...) {
if showDebugLogs{
println(String(format: format, arguments: args))
}
}
これは、追加の引数も受け入れます。必要に応じて、showDebugLogsパラメータ値をtrueまたはfalseに設定するだけです。
Dlog
関数に渡される引数を計算することによるオーバーヘッド(および潜在的な副作用)の問題が依然としてあります。