I’d like to be able to pass all the arguments received in my method to a different method, as generically as possible.
Ideally, this would be done by passing a dictionary or some system variable (similar to _cmd).
In other words, I’m looking for something like the arguments array in javascript, or anything giving me access to the currently called method’s list of arguments.
I think what you are looking for is NSObject’s
forwardInvocation:It gets passed anNSInvocationobject that contains the information you want.NSInvocationalso has a nice method calledinvokeWithTarget:that pretty much forwards the method call just like if you’ve called it directly.The runtime will call
fowardInvocation:if you’re object is sent a message that it doesn’t have a method for, provided you also overridemethodSignatureForSelector:so the runtime can create the NSInvocation object.If all your arguments are objects the method
forwardInvocationmethod will look something like this:The hard part is that you need to make buffers to hold the argument values. If all the arguments are objects or the same type you can use the above code but It’s much more complicated to make a generic function if you use C types. You can use
NSMethodSignature‘sgetArgumentTypeAtIndex:but it returns a string encoding of the type and sizeof wont help you there. You would need to make a map of type names tosize_ts for malloc/calloc.Edit: I added a concrete example of what I glossed over as
// Get the juicy info in methodSignatureAs you can see what you want to do is possible but it’s pretty tough.(Check out Apple’s documentation on Type Encodings and
NSMethodSignature‘ssignatureWithObjCTypes:.)Edit2: This might be better as a separate answer but Here’s a complete (and tested) listing of how you can make use of the listing above to make a method that gets called with an arguments array like in JavaScript.
First make a delegate protocol that the Forwarder object will call when a method is called.
Then make the actual Forwarder:
Now you can instantiate the forwarder that takes some object and forwards any calls to the delegate. If both the target and the delegate are the same object it would work like this:
Running this should output something like:
Again this version will only work with id typed arguments. But can work with other types if you use the above mentioned TypeEncodings.