- Inherits from:
- NSObject
- Conforms to:
- NSCoding
- NSObject (NSObject)
Declared in:
- Foundation/NSInvocation.h
An NSInvocation is an Objective-C message rendered static, an action turned into an object. NSInvocation objects are used to store and forward messages between objects and between applications, primarily by NSTimers and the distributed objects system. An NSInvocation contains all the elements of an Objective-C message: a target, a selector, arguments, and the return value. Each of these elements can be set directly, and the return value is set automatically when the NSInvocation is dispatched.
An NSInvocation can be repeatedly dispatched to different targets; its arguments can be modified between dispatch for varying results; even its selector can be changed to another with the same method signature (argument and return types). This makes it useful for repeating messages with many arguments and variations; rather than retyping a slightly different expression for each message, you modify the NSInvocation as needed each time before dispatching it to a new target.
Creating an NSInvocation requires several steps. Consider this method of the custom class MyCalendar:
- (BOOL)updateAppointmentsForDate:(NSDate *)aDate
updateAppointmentsForDate: takes an NSDate as its only argument, and returns YES or NO depending on whether the appointments could be updated without conflicts. The following code fragment sets up an NSInvocation for it:
SEL theSelector; NSMethodSignature *aSignature; NSInvocation *anInvocation; theSelector = @selector(updateAppointmentsForDate:); aSignature = [MyCalendar instanceMethodSignatureForSelector:theSelector]; anInvocation = [NSInvocation invocationWithMethodSignature:aSignature]; [anInvocation setSelector:theSelector];
The first two lines get the NSMethodSignature for the updateAppointmentsForDate: method. The last two lines actually create the NSInvocation and set its selector. Note that the selector can be set to any selector matching the signature of updateAppointmentsForDate:. Any of these methods can be used with anInvocation:
- (BOOL)clearAppointmentsForDate:(NSDate *)aDate - (BOOL)isAvailableOnDate:(NSDate *)aDate - (BOOL)setMeetingTime:(NSDate *)aDate
Before being dispatched, anInvocation must have its target and arguments set:
MyCalendar *userDatebook; /* Assume this exists. */ NSDate *todaysDate; /* Assume this exists. */ [anInvocation setTarget:userDatebook]; [anInvocation setArgument:&todaysDate atIndex:2];
setArgument:atIndex: sets the specified argument to the value supplied. Every method has two hidden arguments, the target and selector (whose indices are 0 and 1), so the first argument that needs to be set is actually at index 2. In this case, todaysDate will be the NSDate argument to updateAppointmentsForDate:.
To dispatch the NSInvocation, send an invoke or invokeWithTarget: message. invoke only produces a result if the NSInvocation has a target set. Once dispatched, the NSInvocation contains the return value of the message, which getReturnValue: produces:
BOOL result; [anInvocation invoke]; [anInvocation getReturnValue:&result];
Because an NSInvocation doesn't always need to retain its arguments, by default it doesn't do so. This can cause object arguments as well as the target to become invalid if they're automatically released. If you plan to cache an NSInvocation or dispatch it repeatedly during the execution of your application, you should send it a retainArguments message. This method retains the target and all object arguments, and copies C strings so that they're not lost because another object frees them.
Suppose the NSInvocation created above is being used in a time-management application that allows multiple users to set appointments for others, such as group meetings. This application might allow a user's calendar to be automatically updated every few minutes, so that the user always knows what his schedule looks like. Such automatic updating can be accomplished by setting up NSTimer objects with NSInvocations.
Given the NSInvocation above, this is as simple as invoking one NSTimer method:
[NSTimer scheduledTimerWithInterval:600 invocation:anInvocation repeats:YES];
This line of code sets up an NSTimer to dispatch anInvocation every 10 minutes (600 seconds). Note that an NSTimer always instructs its NSInvocation to retain its arguments; thus, you don't need to send retainArguments yourself. See the NSTimer class specification for more information on timers.
NSCoding
- - encodeWithCoder:
- - initWithCoder:
- Creating instances
- + invocationWithMethodSignature:
- Accessing message elements
- - setArgument:atIndex:
- - getArgument:atIndex:
- - setReturnValue:
- - getReturnValue:
- - setSelector:
- - selector
- - setTarget:
- - target
- Managing arguments
- - argumentsRetained
- - retainArguments
- Dispatching an invocation
- - invoke
- - invokeWithTarget:
- Getting the method signature
- - methodSignature
+ (NSInvocation *)invocationWithMethodSignature:(NSMethodSignature
*)signature
- (BOOL)argumentsRetained
See Also: - retainArguments
- (void)getArgument:(void
*)buffer
atIndex:(int)index
buffer must be large enough to accommodate the argument value.
This method raises NSInvalidArgumentException if index is greater than the actual number of arguments for the selector.
See Also: - setArgument:atIndex:, - numberOfArguments (NSMethodSignature)
- (void)getReturnValue:(void
*)buffer
unsigned int length = [[myInvocation methodSignature] methodReturnLength]; buffer = (void *)malloc(length);
If the NSInvocation has never been invoked the result of this method is undefined.
See Also: - setReturnValue:, - methodReturnType (NSMethodSignature)
- (void)invoke
See Also: - getReturnValue:, - setSelector:, - setTarget:, - setArgument:atIndex:
- (void)invokeWithTarget:(id)anObject
See Also: - getReturnValue:, - invoke, - setSelector:, - setTarget:, - setArgument:atIndex:
- (NSMethodSignature *)methodSignature
- (void)retainArguments
For efficiency, newly created NSInvocations don't retain or copy their arguments, nor do they retain their targets or copy C strings. You should instruct an NSInvocation to retain its arguments if you intend to cache it, since the arguments may otherwise be released before the NSInvocation is invoked. NSTimers always instruct their NSInvocations to retain their arguments, for example, because there's usually a delay before an NSTimer fires.
- (SEL)selector
See Also: - setSelector:
- (void)setArgument:(void
*)buffer
atIndex:(int)index
This method raises NSInvalidArgumentException if the value of index is greater than the actual number of arguments for the selector.
See Also: - getArgument:atIndex:, - numberOfArguments (NSMethodSignature)
- (void)setReturnValue:(void
*)buffer
See Also: - getReturnValue:, - methodReturnLength (NSMethodSignature), - methodReturnType (NSMethodSignature)
- (void)setSelector:(SEL)selector
See Also: - selector
- (void)setTarget:(id)anObject
See Also: - target, - invokeWithTarget:
- (id)target
nil
if the receiver
has no target.See Also: - setTarget: