The NSInvocation class is designed to represent an Objective-C message. NSInovation instances encapsulates all the attributes of an Objective-C message. They know the message's receive, the message name (both the selector and method signature), and all the message's arguments. After invoking an NSInvocation, the message's return value may be retrieved from the NSInvocations.
One point of confusion for many developers is how messages are named. Each name has two parts, the selector and the method signature. A selector is the message's name without any type information, for example "countOfObjectsOfType:" is a selector. To build a complete message, the types of each argument and return value's type need to be known. This type information is known as a method signature. The class NSMethodSignature encapsulates this information.
// if you must use an id type, then use a cast when sending the messageid myObject;value = [(ClassA *)myObject countOfObjectsOfType:aType];// otherwise, use static typing instead of a generic id to disambiguateClassA *myObject;value = [myObject countOfObjectsOfType:aType];
At runtime, however, the receiver is known, and it is possible to simply ask it for the correct message signature, like this:
NSMethodSignature* mySignature = [myObjectmethodSignatureForSelector:@selector(countOfObjectsOfType:)];
a sample,
NSString *receivingString = [receiver stringValue];NSString *messageString = [message titleOfSelectedItem];SEL selector = NSSelectorFromString(messageString);NSMethodSignature *methodSignature = [receivingStringmethodSignatureForSelector:selector];NSInvocation *invocation = [NSInvocationinvocationWithMethodSignature:methodSignature];
Every Objective-C method has two hidden arguments. The first and most commonly used arguments is self. The second, containing the selector that invoked the method, is called _cmd.
[invocation setTarget:receivingString]; // argument 0 is "self"[invocation setSelector:selector]; // argument 1 is "_cmd"
Returning to the example, the next step is to configure the arguments for the invocation.
The -setArgument:atIndex: method of NSInvocation is used for this.The messagesbeing sent can have 0, 1, or 2 arguments, and the tag of the selected pop-up buttonitem tells how many arguments to set up. Because the hidden arguments self and _cmdtake up spots 0 and 1 in the argument list, the first argument to the method is actually argument 2.Also when using the -setArgument:atIndex: method, pointers to objectpointers must be used instead of just a pointer to the object. Here’s the code:int numberOfArguments = [[message selectedItem] tag];if (numberOfArguments > 0){NSString *argumentString1 = [argument1 stringValue];[invocation setArgument:&argumentString1 atIndex:2];if (numberOfArguments > 1){NSString *argumentString2 = [argument2 stringValue];[invocation setArgument:&argumentString2 atIndex:3];}}
Here is the code to invoke the message and interpret the return value:
[invocation invoke];void *returnValue = NULL;[invocation getReturnValue:&returnValue];const char *returnType = [methodSignature methodReturnType];