views:

199

answers:

3

I'm not sure this is possible, but in ruby, you can dynamically call a method using send

e.g. if I want to invoke the bar method for the object, foo, I can use

foo.send("bar")

Is there any way of doing something similar using objective-c?

tks!

A: 
if ( [foo respondsToSelector:NSSelectorFromString(@"bar")] ) [foo performSelector:NSSelectorFromString(@"bar")];
pxl
+12  A: 

There are several options, as far as I know

  1. You could use NSObject's performSelector: method. This, however, is only really good for methods that have few or no arguments.
  2. Use the NSInvocation class. This is a bit heftier, but is a lot more flexible.
  3. You might be able to use objc_msgSend(), but it's probably a bad idea to call it directly, due to other stuff that the runtime might be doing behind the scenes.
htw
Right, there's only `performSelector:`, `performSelector:withObject:`, and `performSelector:withObject:withObject:` -- more than 2 arguments and it's no longer a viable choice. I think NextSTEP used to have a `performv:` allowing for variable args, or something like that, but I'm not quite sure...
ephemient
More than two arguments is when you use NSInvocation, or switch to using a dictionary as an argument. It's not that hard, it's just a few more calls.
Kendall Helmstetter Gelner
+3  A: 

For general use (method with a return value and any number of arguments), use NSInvocation:

if ([target respondsToSelector:theSelector]) {
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
        [target methodSignatureForSelector:theSelector]];
    [invocation setTarget:target];
    [invocation setSelector:theSelector];
    // Note: Indexes 0 and 1 correspond to the implicit arguments self and _cmd, 
    // which are set using setTarget and setSelector.
    [invocation setArgument:arg1 atIndex:2]; 
    [invocation setArgument:arg2 atIndex:3];
    [invocation setArgument:arg3 atIndex:4];
    // ...and so on
    [invocation invoke];
    [invocation getReturnValue:&retVal]; // Create a local variable to contain the return value.
}
Martin Gordon