10

現在、私は自分のプロジェクト用に 2 つのアプリをビルドしています。1 つはリリース用、もう 1 つはデバッグ用です (唯一の変更点は、署名に使用されるプロビジョニング プロファイルとエンドポイントです)。いくつかのポリシーにより、ipa ファイルをローカルに作成するべきではありません。そのため、スクリプトに基づいて、maven を使用してこれら 2 つのバージョン (リリースとデバッグ) をビルドします。同じポリシーのため、出力はアプリケーション ( NSLog、printf...) から完全に削除する必要があります。私はプリプロセッサ マクロを認識していますが、誰かが (知らないうちに) マクロを変更して、私が達成したいことを危険にさらす可能性があるため、それらに依存したくありません。だから私が欲しいのは:

  1. シミュレーターを使用しているとき、または実際のデバイスで直接実行しているときは、必要なものをすべてログアウトできます
  2. Maven を使用してアプリケーションをビルドすると、NSLogsそれらが削除または無効化されていることが確認されます。

Maven は、実際にビルドを行うためにリモート リポジトリにあるものに依存しているため、リモート リポジトリのコミット中にこのログを無効にする方法があれば、それも解決策です。

4

4 に答える 4

1

これは興味深い要求ですが、スキップされるログごとに多少の関数呼び出しのオーバーヘッドを許容できる場合は実行可能です。EtPanKit フレームワーク内には、ログ関数を呼び出そうとしているファイルがファイル内の事前定義されたクラスの配列と一致するかどうかをチェックする優れた機能がありInfo.plistます。優れたデバッグ フィルターであることに加えて、リリース時に行う必要があるのは、plist からすべてのキーを削除するか、キーに関連付けられた値を持たないリリース ビルドで別のキーを指定することだけLEPLogEnabledFilenamesです。

リンクの腐敗を防ぐために、関数自体と、関数を呼び出しやすくする関連マクロを次に示します。

#define LEPLogStack(...) LEPLogInternal(__FILE__, __LINE__, 1, __VA_ARGS__)
#define LEPLog(...) LEPLogInternal(__FILE__, __LINE__, 0, __VA_ARGS__)

#import <Foundation/Foundation.h>
#import <libgen.h>
#import <time.h>
#import <sys/time.h>
#include <execinfo.h>
#include <pthread.h>

static NSSet * enabledFilesSet = nil;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

void LEPLogInternal(const char * filename, unsigned int line, int dumpStack, NSString * format, ...)
{
    va_list argp;
    NSString * str;
    NSAutoreleasePool * pool;
    char * filenameCopy;
    char * lastPathComponent;
    struct timeval tv;
    struct tm tm_value;
    //NSDictionary * enabledFilenames;

    pool = [[NSAutoreleasePool alloc] init];

    pthread_mutex_lock(&lock);
    if (enabledFilesSet == nil) {
        enabledFilesSet = [[NSSet alloc] initWithArray:[[NSUserDefaults standardUserDefaults] arrayForKey:LEPLogEnabledFilenames]];
    }
    pthread_mutex_unlock(&lock);

    NSString * fn;
    fn = [[NSFileManager defaultManager] stringWithFileSystemRepresentation:filename length:strlen(filename)];
    fn = [fn lastPathComponent];
    if (![enabledFilesSet containsObject:fn]) {
        [pool release];
        return;
    }

    va_start(argp, format);
    str = [[NSString alloc] initWithFormat:format arguments:argp];
    va_end(argp);

    NSString * outputFileName = [[NSUserDefaults standardUserDefaults] stringForKey:LEPLogOutputFilename];
    static FILE * outputfileStream = NULL;
    if ( ( NULL == outputfileStream ) && outputFileName )
    {
        outputfileStream = fopen( [outputFileName UTF8String], "w+" );
    }

    if ( NULL == outputfileStream )
        outputfileStream = stderr;

    gettimeofday(&tv, NULL);
    localtime_r(&tv.tv_sec, &tm_value);
    fprintf(outputfileStream, "%04u-%02u-%02u %02u:%02u:%02u.%03u ", tm_value.tm_year + 1900, tm_value.tm_mon + 1, tm_value.tm_mday, tm_value.tm_hour, tm_value.tm_min, tm_value.tm_sec, tv.tv_usec / 1000);
    //fprintf(stderr, "%10s ", [[[NSDate date] description] UTF8String]);
    fprintf(outputfileStream, "[%s:%u] ", [[[NSProcessInfo processInfo] processName] UTF8String], [[NSProcessInfo processInfo] processIdentifier]);
    filenameCopy = strdup(filename);
    lastPathComponent = basename(filenameCopy);
    fprintf(outputfileStream, "(%s:%u) ", lastPathComponent, line);
    free(filenameCopy);
    fprintf(outputfileStream, "%s\n", [str UTF8String]);
    [str release];

    if (dumpStack) {
        void * frame[128];
        int frameCount;
        int i;

        frameCount = backtrace(frame, 128);
        for(i = 0 ; i < frameCount ; i ++) {
            fprintf(outputfileStream, "  %p\n", frame[i]);
        }
    }

    if ( outputFileName )
    {
        fflush(outputfileStream);
    }

    [pool release];
}
于 2013-08-14T16:24:23.817 に答える
1

プリプロセッサ マクロに依存したくないことは理解していますが、プリプロセッサを使用して NSLog ステートメントを削除する簡単な方法があります。

プレフィックス ヘッダーに次を追加します。

#ifndef DEBUG
#define NSLog(...)
#endif

DEBUG が定義されていない場合、すべての NSLog ステートメントはアプリ コード全体でプリプロセッサによって削除されます。ビルド設定で DEBUG が自動的に追加されない場合は、 #define DEBUG ステートメントを追加して、リリース用のビルド時にコメント アウトするだけです。

printf() ステートメントでも同じことができます。

リリースのために NSLog を取り除くためにリリースしたアプリでこれをうまく使用しました。

于 2013-10-07T21:45:21.740 に答える