views:

1340

answers:

3

I have a method that varies by a single method call inside, and I'd like to pass the method/signature of the method that it varies by as an argument... is this possible in Objective C or is that too much to hope for?

+7  A: 

NSInvocation is a class for wrapping up a method calls in an object. You can set a selector (method signature), set arguments by index. You can then set a target and call invoke to trigger the call, or leave the target unset and use invokeWithTarget: in a loop of some sort to call this on many objects.

I think it works a little like this:

NSInvocation *inv = [[NSInvocation alloc] init];
[inv setSelector:@selector(foo:bar:)];
[inv setArgument:123 atIndex:0];
[inv setArgument:456 atIndex:1];

for (MyClass *myObj in myObjects) {
  [inv invokeWithTarget:myObj];
}

Or if you dont want to pass invocation objects into this method you can use the SEL type to accept a selector (method signature).

-(void)fooWithMethod:(SEL)selector;

Then assign the selector to an invocation object in order to call it on objects.

Squeegy
+2  A: 

Or if you're using the fooWithMethod:(SEL)selector approach, just do [myObject performSelector:selector] on it, if it has no other arguments.

See NSObject.h ( file:///Developer/SDKs/MacOSX10.5.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObject.h ) for details.

cdespinosa
+1  A: 

As said before you can pass the selector of the method you want to call. Using a selector there are different ways to actually call the method:

  1. using NSObjects performSelector:, performSelector:withObject: and performSelector:withObject:withObject: methods
  2. using a NSInvocation object
  3. or directly using objc_msgSend or objc_msgSend_stret
  4. using the IMP of that method which you can get using methodForSelector:

Which one to use really depends on the situation. If the performance is not critical I’d go ahead with 1 if you need to pass in 0, 1 or 2 objects. If the performSelector:... methods don’t match I’d go with 2 or 3. Since setting up an NSInvocation object requires a lot of boilerplate code I prefer 3, but I guess that’s a matter of personal choice, unless there are performance issues.

If the performance of those method calls does matter I’d use 3 or 4. 3 should be faster unless you can cache the IMPs. But depending on your code this may not be feasible or doesn’t really help. So here you must profile the code and see which one is better for you.

Sven