[NSString stringWithFormat:]をラップする適切な方法は何ですか?
-
06-07-2019 - |
質問
署名のあるメソッドがあると仮定します:
+ (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 *)を取得できると仮定している理由は、 STDARG(3)のマニュアルページ。メソッドを完全に間違っている場合は、自由にメソッドを完全に書き換えてください。
解決
あなたが望むものは次のようなものだと思います:
+ (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];
}
stdarg.h
va _
*マクロは、関数(またはこの場合はメソッド)が&quot;で指定された可変数の引数を取るときに使用されます。 ...
&quot;。 va_start()
は、可変数の引数の開始位置を見つけるために使用されます。そのため、可変数の引数の開始位置を決定するために、関数/メソッドの最後の引数(&quot; ...
&quot;の直前のもの)を知る必要があります。実際に内部で行われることは非常にABI /コンパイラ固有であるため、これはやや単純化された説明です。最も重要な点は、 va_start()
の2番目の引数が常に変数の名前である「&quot; ...
&quot;の直前」であることです。
va_end()
は「呼び出される」必要があります; (実際にはマクロであり、関数ではありません)最大限の移植性のために。繰り返しになりますが、この変数引数全体は、深い、深い黒魔術です。コンパイラとABIの仕様によっては、 va_end()
は何も実行しない場合があります。一方、 va_end()
を使用しないと、スタックフレーム(ある場合)がないため、 return
ステートメントに到達したときにプログラムがクラッシュする可能性があります実際にリターンを実行するように適切に設定されました。
他のヒント
ほとんど手に入れました。いくつかの調整:
+ (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];
}
それはあなたが探していることをするはずです。