I will answer your question like this: Don't use NSInvocation
. It's just a friendly advice to avoid that if possible.
There are many nice ways to do callbacks in Objective-C, here are two that may be useful for you:
- Blocks: Defined in context, choose any argument count and types, possible issues with memory too. There are many resources on how to use them.
performSelector: max 2 object arguments, invoked using:
[target performSelector:selector withObject:data withObject:args];
In addition, when I need to invoke a selector with 4 arguments I still don't use NSIvocation
, but rather call objc_msgSend
directly:
id returnValue = objc_msgSend(target, selector, data, /* argument1, argument2, ... */);
Simple.
Edit: With objc_msgSend
you need to be careful with the return value. If your method returns an object, use the above. If it returns a primitive type, you need to cast the objc_msgSend
method so the compiler knows what's going on (see this link). Here's an example for a method that takes one argument and returns a BOOL:
// Cast the objc_msgSend function to a function named BOOLMsgSend which takes one argument and has a return type of BOOL.
BOOL (*BOOLMsgSend)(id, SEL, id) = (typeof(BOOLMsgSend)) objc_msgSend;
BOOL ret = BOOLMsgSend(target, selector, arg1);
If your method returns a struct, things are a bit more complicated. You may (but not always) will need to use objc_msgSend_stret
-- see here for more info.
Edit: - this line have to be added to the code, or Xcode will complain:
#import <objc/message.h>
or
@import ObjectiveC.message;