Invocation

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 message
id myObject;
value = [(ClassA *)myObject countOfObjectsOfType:aType];
// otherwise, use static typing instead of a generic id to disambiguate
ClassA *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 = [myObject
methodSignatureForSelector:@selector(countOfObjectsOfType:)];

a sample,

NSString *receivingString = [receiver stringValue];
NSString *messageString = [message titleOfSelectedItem];
SEL selector = NSSelectorFromString(messageString);
NSMethodSignature *methodSignature = [receivingString
methodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation
invocationWithMethodSignature: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 messages
being sent can have 0, 1, or 2 arguments, and the tag of the selected pop-up button
item tells how many arguments to set up. Because the hidden arguments self and _cmd
take 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 object
pointers 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];

 

 

 

 

 

 

posted on 2012-07-08 14:57  grep  阅读(590)  评论(0编辑  收藏  举报