Multi-Inheritance
Objective-C does not support multi-inheritance, but we have methods to implement pseudo-inheritance.
For example, if object A is added, it cannot process the message fun, But object B can process the message. In this case, object A is inherited from Class C, so object a cannot inherit from object B. We can forward messages to object B that can process fun messages by means of message forwarding.
Of course, this can be achieved
1 A: 2 -fun 3 { 4 if([B respondTo:@selector(fun)]) 5 { 6 return [B fun]; 7 } 8 return self; 9 }
|
This is a simple way to forward messages, but this method is not suitable, especially when many messages are processed by a but cannot be processed by, you need to implement various fun methods to provide each method. When writing the code, the set of messages that can be processed must be determined, that is, static messages.
There is a solution to solve this problem:Forwardinvocation: Method. This method inherits from nsobject. However, the implementation of this method in nsobject simply calls doesnotrecognizeselector:
We need to rewrite the forwardinvocation method of Class A for message forwarding to forward messages to objects that can process fun messages.
- (void)forwardInvocation:(NSInvocation *)anInvocation |
{ |
if ([B respondsToSelector:[anInvocation selector]) |
[anInvocation B]; |
else |
[super forwardInvocation:anInvocation]; |
} |
Another key step is to override the methodsignatureforselector method, which is called when messages that cannot be processed are sent to the object. This method can be used to determine whether the message fun is valid for registration. If you have registered fun, information such as the address of the fun message will be returned. If not, nil will be returned, and crash will be dropped. Therefore, we need to register the fun message as a valid message.
1-(nsmethodsignature *) methodsignatureforselector :( SEL) Selector 2 { 3 nsmethodsignature * Signature = [Super methodsignatureforselector: Selector]; 4 5 If (! Signature) // if no fun message is registered in the parent class, register B 6 Signature = [B methodsignatureforselector: Selector]; 7 8 return signature; 9}
|
In this way, the message fun will be forwarded to B.
After a message is sent to an object, the system processes the message.
1. First, send the message [A fun];
2. The system will check whether a can respond to this fun message. If yes, a will respond.
3. If the message cannot be responded, call methodsignatureforselector to check whether the message is valid, including querying in the parent class.
4. Call forwardinvocation: At this time, step 3 returns the nil or the Message Address that can process the message. If nil is used, it is Crash. If there is an address that can process fun messages, the forwarding is successful.
Http://www.cppblog.com/cokecoffe/archive/2012/05/23/175943.html