variadic method
Cのprintfのように可変引数つきの関数のことをvariadic functionと呼ぶ。
Variadic Functions - The GNU C Library
Objectivce-Cのvariadic function(この場合はvaliadic methodか)はCに習ってシグネチャを以下のように書ける。
- (id)variadicMethod:(id) args, ...;
使う側は以下のように書ける。
[obj variadicMethod:arg1, arg2, arg3,....];
可変長の引数はJavaやC#等の現代の比較的静的な型付け言語にも実装されており、非常に便利なのだが、実際にこの可変引数を使ったメソッドを自ら実装することを考えた場合、Objective-CはCと同様にva_マクロを使う必要があり、面倒である。
例えば現在書いているライブラリィのユーティリティではリフレクションよろしく、オブジェクトとメッセージ(メソッド)名前、与えるパラメタから実行を動的に行うためのメソッドを実装したいと考えている。
NSObject+MethodUtil.h
- (id)invokeMethodByNamed:(NSString*)name ForParams:(id) params,...;
可変長の引数を内部でva_listで展開してパラメタを取り出すのは基本通りなのだが、この実装で重要なのはランタイムAPIのobjc_msgSendを使うことであり、こによってシグネチャからobjc_msgSendへ可変長引数を渡す必要が出てくる。そして、この書き方が判らない。
NSObject+MethodUtil.m
- (id)invokeMethodByNamed:(NSString*)name ForParams:(id) params,... { va_list args; va_start(args, params); { **** objc_msgSendにどうやって可変長の引数を一度に渡す? **** } va_end(args); }
ここの解決法が見つからない場合は、NSInvocation、NSMethodSignatureを使うことで同様のコーディングは出来ると思うのだが、NSInvocationクラスの内部ではobjc_msgSendを呼び出していることが想像に難くない訳で、そうであれば素直にobjc_msgSendを使いたいと思うのだ。
うーむ。
追記:
ひょっとしてObjective-Cのコンパイラが__VA_ARGS__マクロをサポートしていれば出来たりするのかな。