2009-07-30 27 views
7

私は、署名付きのメソッドがあると仮定します:[NSString stringWithFormat:]をラップする適切な方法は何ですか?

+ (NSString *) myFormattedString:(NSString *)format, ...; 

そして、それは私の選択の文字列の前にしたい(例えば、@ "Foo:")。私は最良の方法は[myString initWithFormat:arguments:]を使うことだと思いますが、どのようにこのメソッドを実装しますか?

次のようにしてみましたが、コメントに指定されている警告が表示されます:

+ (NSString *) myFormattedString:(NSString *)format, ... { 
    char *buffer; 
    [format getCString:buffer maxLength:[format length] encoding:NSASCIIStringEncoding]; 

    va_list args; 
    va_start(args, buffer); // WARNING: second parameter of 'va_start' not last named argument 

    NSString *str = [[NSString alloc] initWithFormat:format arguments:args]; 
    [str autorelease]; 

    return [NSString stringWithFormat:@"Foo: %@.", str]; 
} 

va_start()が(char *私は manual page of STDARG(3)で見た例のためです。私が完全に間違っていたら、メソッドを完全に書き直してください。

答えて

15

私が何をしたいことのようなものだと思う:で指定された関数(または、この場合は、この方法は)」、可変個の引数を取るときstdarg.hva_ *マクロが使用されている

+ (NSString *) myFormattedString:(NSString *)format, ... { 
    va_list args; 
    va_start(args, format); 
    NSString *str = [[[NSString alloc] initWithFormat:format arguments:args] autorelease]; 
    va_end(args); 
    return [NSString stringWithFormat:@"Foo: %@.", str]; 
} 

... "。 va_start()は、可変数の引数が始まる場所の始まりを見つけるために使用されます。そのため、可変数の引数の開始位置を決定するために、関数/メソッドの最後の引数( "..."の直前のもの)を知る必要があります。フードの下で実際に起こるのは非常にABI /コンパイラ固有のものなので、これはやや簡単な説明です。最も重要な点は、va_start()への第2引数が常に「...」の直前の変数の名前であることです。

va_end()は、移植性を最大限に高めるために「呼び出される」(実際はマクロであり、関数ではありません)。ここでも、この可変引数の全体は深く深い黒の魔法です。コンパイラとABIの仕様によっては、va_end()はまったく何もしないかもしれません。一方、va_end()を使用しないと、スタックフレーム(ある場合でも)が実際にリターンを実行するように正しく設定されていないため、returnステートメントに達したときにプログラムがクラッシュする可能性があります。

+0

私はva_start()がどのように動作するのか誤解しました。私はhttp://numbergrinder.com/node/35がそれを十分にはっきり説明していないと思う。私は、va_start()の2番目のパラメータは、関数に送られたパラメタの数の実際の数であると考えました。それはフォーマット文字列の中にエスケープされていない%がどれくらいあるかに基づいて数を決定するフォーマット文字列を取った 'オーバーロード'を持っていたこと...それはあなたが決定する必要がないあなた自身を数えてください。説明ありがとう。 – Senseful

8

あなたはほとんどそれを持っています。

+ (NSString *) myFormattedString:(NSString *)format, ... { 
    va_list args; 
    va_start(args, format); 

    NSString *str = [[NSString alloc] initWithFormat:format arguments:args]; 
    [str autorelease]; 

    va_end(args); 

    return [NSString stringWithFormat:@"Foo: %@.", str]; 
} 

あなたが探しているものを行う必要があります。

関連する問題