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?
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.
Indices 0 and 1 indicate the hidden arguments self and _cmd, respectively; you should set these values directly with the target and selector properties. Use indices 2 and greater for the arguments normally passed in a message.
- source –
Forsworn 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.
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:
- using
NSObject
sperformSelector:
,performSelector:withObject:
andperformSelector:withObject:withObject:
methods - using a
NSInvocation
object - or directly using
objc_msgSend
orobjc_msgSend_stret
- using the
IMP
of that method which you can get usingmethodForSelector:
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.
© 2022 - 2024 — McMap. All rights reserved.
NSMethodSignature* sig = [self methodSignatureForSelector:@selector(foo:bar:)];
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:sig];
From there it should work. – Forsworn