NSObjectのperformSelectorは、Objective-Cのオブジェクトしか渡せないので、int型の値を渡すだけでもたいへんです。NSObjectを継承したInteger型みたいなのを作るか、NSValueを使っているひとが多いと思います。
今回は、intでもstd::vectorでも、C++のオブジェクトをなんでも渡せる、performSelectorの代わりとなる関数を作りました。こんな感じです:
#import <Foundation/Foundation.h> #import <boost/mpl/identity.hpp> #import <iostream> #import <vector> #import <boost/range/algorithm/for_each.hpp> #import <boost/lambda/lambda.hpp> #import <boost/assign/list_of.hpp> template <class A1> void invokeSelector(id target, SEL action, typename boost::mpl::identity<A1>::type a1) { typedef void(*Action)(id, SEL, A1); Action func = (Action)[target methodForSelector:action]; (*func)(target, action, a1); } template <class A1, class A2> void invokeSelector(id target, SEL action, typename boost::mpl::identity<A1>::type a1, typename boost::mpl::identity<A2>::type a2) { typedef void(*Action)(id, SEL, A1, A2); Action func = (Action)[target methodForSelector:action]; (*func)(target, action, a1, a2); } template <class A1, class A2, class A3> void invokeSelector(id target, SEL action, typename boost::mpl::identity<A1>::type a1, typename boost::mpl::identity<A2>::type a2, typename boost::mpl::identity<A3>::type a3) { typedef void(*Action)(id, SEL, A1, A2, A3); Action func = (Action)[target methodForSelector:action]; (*func)(target, action, a1, a2, a3); } @interface Foo : NSObject - (void)doSomethingI:(int)x; - (void)doSomethingV:(const std::vector<int>&)x; @end @implementation Foo - (void)doSomethingI:(int)x { std::cout << x << std::endl; } - (void)doSomethingV:(const std::vector<int>&)x { boost::for_each(x, std::cout << boost::lambda::_1 << ' '); } @end @interface Bar : NSObject - (void)main; @end @implementation Bar - (void)main { Foo* foo = [[Foo alloc] init]; invokeSelector<int>(foo, @selector(doSomethingI:), 5); invokeSelector<const std::vector<int>&>(foo, @selector(doSomethingV:), boost::assign::list_of(3)(1)(4)); [foo release]; } @end int main() { Bar* bar = [[Bar alloc] init]; [bar main]; [bar release]; }
5 3 1 4
いつ頃からかはわかりませんが、最近のXcode(GCC)では、関数テンプレートの中でObjective-Cの構文を使えるようになったので、とても簡単に作れました。
methodForSelectorでセレクターの関数ポインタが得られるので、それに引数を渡してるだけです。
これでObjective-C++での開発がかなり楽になります。