- Introspection
- Protocols
- Extending Classes
- Informal Protocols
- Second-Chance Dispatch
- Summary
Second-Chance Dispatch
In C++, you don't send messages, you call member functions. This is an important distinction, because it means that calling methods is semantically similar to a function call. Objective-C adds another layer of abstraction. If you send a message to an Objective-C object that it doesn't understand, an exception will be thrown. This isn't done by the language, however.
The runtime library has a fallback mechanism when no method is found for a selector. It calls a method that introspects the receiver for some type information, wraps up the call in an NSInvocation object, and then passes this to the object's -forwardInvocation: method.
The NSInvocation object encapsulates the receiver, the selector, and the arguments. You can use this idea for things like higher-order messaging. Consider the following example usage:
[[anArray map] toUppercase];
The -map method on the array returns a proxy object with a forwardInvocation: method implemented like this:
- (void) forwardInvocation:(NSInvocation*)anInvocation { SEL selector = [anInvocation selector]; NSMutableArray * mappedArray = [NSMutableArray array]; FOREACHI(array, object) { if([object respondsToSelector:selector]) { [anInvocation invokeWithTarget:object]; id mapped; [anInvocation getReturnValue:&mapped]; [mappedArray addObject:mapped]; } } [anInvocation setReturnValue:mappedArray]; }
The FOREACHI macro is from Étoilé, and simply performs some IMP caching on an NSEnumerator. When you send the -toUppercase message to the map proxy, it iterates over every object in the array; checks whether it responds to the selector; and, if it does, calls the method with the arguments. The return value is then added to a new array.
This is pretty much impossible to do in C++. You can use the command pattern to do something similar, but only by implementing your own dispatch mechanism on top of C++.