可変長引数でオブジェクトを簡単に受け取る : Objective-C プログラミング

PROGRAM


可変長引数でオブジェクトを簡単に受け取る

Objective-C では、状況によって個数の異なるオブジェクトを引数で受け取るメソッドを実装したいときに、わざわざ NSArray 型の引数を用意してもらわなくても、簡単に受け取れるようにすることができます。

 

そのためには、まずはメソッドのプロトタイプとして、次のように宣言します。

// メソッドの引数は可変長引数として宣言します。最後に nil で終わることを明示すると便利です。

- (void)setName:(NSString*)aName values:(NSString*)values, ... NS_REQUIRES_NIL_TERMINATION;

このように、この例では aName で指定された名前と併せて、任意の数の NSString* 型の引数を取るメソッドの宣言ができました。

ここで、最後に "NS_REQUIRES_NIL_TERMINATION" というキーワードを指定していますが、これを指定することで、Xcode でこのメソッドを使用しようとしたときに、最後の可変長引数が nil で終わる必要があることが、プログラマに分かるように表示されるので便利です。

 

このようなメソッドの実装は、例えば次のような感じで行います。

// nil で終わる可変長引数を取るメソッドの実装です。

- (void)setName:(NSString*)aName values:(NSString*)argValues, ...

{

// 例えば aName の値は name プロパティに保持するものとします。

self.name = aName;

 

// 可変長引数を取り出すために、va_start 関数を使って、最初の 1 つ目の値の位置を取得します。

va_list arguments;

 

va_start(arguments, argValues);

 

// 可変長引数の最初の値は、引数で指定した変数名を使用します。

NSString* value = argValues;

 

// 可変長引数が nil になるまで繰り返します。

while (value)

{

// ここで、それぞれの引数についての処理を行います。

 

 

// 次の引数を取得します。

value = va_arg(arguments, typeof(NSString*));

}

 

// 最後に可変長引数の扱いが終わったことを va_end 関数を使って伝えます。

va_end(arguments);

}

このようにして、任意の数の引数を簡単に処理することができます。

このように実装すると、このメソッドを呼び出す際にも、例えば可変長引数をわざわざ [NSArray arrayWithObjects:@"A", @"B", @"C", nil] というように準備してそれを引数に指定しなくても、最初から @"A", @"B", @"C", nil として、引数を渡せるようになるので簡単です。

 

実装の際の注意点としては、最初の引数は va_arg では取得できないところでしょうか。

最初の引数は、メソッドの引数のところに記されている引数から値を通常通り取得します。その次の引数からは va_arg を使って順次取得して行く形になります。

 

可変長引数で受け取った情報から文字列を生成したい場合

書式文字列と可変長引数を受け取った情報をそのまま使って NSString を作成したい場合には、NSString の initWithFormat:arguments: メソッドを使うと簡単です。

こちらについては 可変長引数を使って書式文字列を展開する の方に詳しい方法を記してあるので参考にしてみてください。

[ もどる ]