2013-06-06 4 views
6

NSLogを実行するカスタムNSLog()メソッドDNSLog()を作成しようとしていますが、デバッグ変数がtrueの場合にのみ実行されます。カスタムNSLogメソッド(バリアント)

-(void)DNSLog:(NSString *)formatString, ... 
{ 
    if(debug){ 
     va_list args; 
     va_start(args, formatString); 
     NSLog([[NSString alloc] initWithFormat:formatString arguments:args]); 
     va_end(args); 
    } 
} 

しかし、私は

DNSLog(@"Hello %d",x); 

を使用して、それを呼び出してみたとき、私はコンパイルエラーが表示されます。

Undefined symbols for architecture i386: 
    "_DZNSLog", referenced from: 
     -[RestaurantInfoViewController viewDidLoad] in RestaurantInfoViewController.o 
ld: symbol(s) not found for architecture i386 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

私はリファレンスとしてこれを使用している:私はhttp://www.cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html

間違っている?

+5

私は先進的なものに取り掛かる前にCを学んでいると思います。 C関数の構文とObjective-Cの方法を区別することさえできないようです... –

+1

さらに、あなたのコードは文字列の攻撃/エラーのフォーマットに脆弱です。代わりに 'NSLogv(formatString、args);'を使うべきです。 –

答えて

14

あなたは方法機能を混同している - のObjective-Cには両方を持っています。 NSLogは標準関数なので、NSLog(...)と呼びます。方法を定義しました:

-(void)DNSLog:(NSString *)formatString, ... 

しかし、関数として呼び出そうとしました。あなたのメソッドを呼び出すには、あなたは何をする必要があります:あなたのコードがコンパイルさ

[self DNSLog:@"Hello %d", x]; 

として、あなたは、グローバルまたはインスタンスdebug変数を持っている必要があります。 グローバルの場合はDNSLogを関数として定義できます(debugがメソッドに直接アクセスできるのはインスタンス変数の場合は機能しません)。関数は次のように起動します。

void DNSLog(NSString *formatString, ...) 

関数の本体はメソッドと同じです。

NSLogには、フォーマット文字列と引数が一致することを確認するために、コンパイラが書式文字列と引数をチェックすることをコンパイラに示すために、属性がNS_FORMAT_FUNCTIONです。インタフェースやヘッダファイルに

void DNSLog(NSString *formatString, ...) NS_FORMAT_FUNCTION(1,2); 

-(void)DNSLog:(NSString *)formatString, ... NS_FORMAT_FUNCTION(1,2); 

か:あなたのメソッドや関数の書き込みのためにこれを行うにしてください。

HTH。

+0

ありがとう...はい、私はその間違いを認識しました。今はすべて働いています:) – Kyuubi

+1

@ Kyuubi - はい、これを入力している間に自分でいくつか考え出しましたが、NS_FORMAT_FUNCTIONを忘れないでください。ロット。 – CRD

+0

入手しました。私の機能に同じものを付け加えました。 – Kyuubi

12

カスタムメソッドを使用する代わりに、このマクロをアプリ(.pchファイルなど)に追加してみてください。

#ifdef DEBUG 
#define MyLog(x, ...) NSLog(@"%s %d: " x, __FUNCTION__, __LINE__, ##__VA_ARGS__) 
#else 
#define MyLog(x, ...) 
#endif 

これはデバッグモードのときにMyLogを呼び出すカスタムログを実行し、リリース時には何もしません。また、ログのファイルや行番号などの有用な情報も表示されます。

+1

実際に彼の質問は、 "デバッグ変数が真である"ときのみログを記録することでした。彼のコードは、彼が制御している別のデバッグ変数を持っていることを示しているようです。また、H2CO3はそれを彼が見ているように呼ぶだけです。私もそう感じた。私は答えを自分自身で提供することはめったにありません。なぜなら、人がコピーして貼り付けるだけで、それが書かれたとおりにはうまくいかないときには失われてしまうのです。私は人々が*自分が書いているコードを理解するべきだと感じています。 – borrrden

+0

それで彼はそれを理解できるように彼に知らせるのに役立つ答えを投稿する解決策ではありませんか?おそらく、私たちは実際にopメソッドがこのメソッドを学習し実装するのを助けるポストを作成します。そしてそれに加えて、何かをするために違う方法を共有することは間違ってはいけませんが、私は今あなたの意見を見ています。 – Eric

+0

ありがとうございます。それも同様に動作します! しかし、将来は、Log Functionに複雑なブール式とネストされたif-elseがあるかもしれないので、MACROの代わりに新しい関数をまとめて実装しようとしていました。 – Kyuubi

9

初心者にあなたの非常に「貴重な」、「励ましている」、「支持する」回答をいただき、ありがとうございます。

私は私のミスを発見し、ここで修正作業コードです:

void ZNSLog(NSString *format, ...){ 
    if(!ENABLE_DEBUGGING) 
     return; 
    va_list args; 
    va_start(args, format); 
    NSLogv(format, args); 
    va_end(args); 
} 

ZNSLog(@"Hello"); 

私が使っていた以前の方法はObjective Cの方法私はCを使用して呼び出すようにしようとしていた

-(void)DNSLog:(NSString *)formatString, ... 

ました関数呼び出し。