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
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.
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:
NSObject
s performSelector:
, performSelector:withObject:
and performSelector:withObject:withObject:
methodsNSInvocation
objectobjc_msgSend
or objc_msgSend_stret
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 IMP
s. 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.
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 for details.