We want to use a small example of a simple, popular understanding of what is the message forwarding and how to forward the message, I hope that after reading this article, we will thoroughly understand OC news.
First, you need to know these two concepts:
The call method in OC is to send a message to the object.
Like what:
This is actually the message that sends the run to person this object.
So the question is, what happens when the Run method is only defined without implementation?
is the classic error.
1 |
*** Terminating app due to uncaught exception ‘NSInvalidArgumentException‘ , reason: ‘-[Person run]: unrecognized selector sent to instance |
OK, the premise has been said, we will find the reason for this error.
First, when the method is called, the system will see if the object can receive the message (see if the class has this method, or if it does not implement this method.) ), if you can not and only in the case, will invoke the following methods, give you the opportunity to "remedy", you can first understand a few sets of options to prevent the program crash, we are using these scenarios for message forwarding, note that the previous set of scenarios after the implementation of a set of methods will not be executed. If you do not deal with these sets of solutions, then the program will be error crash.
For example: When playing football, the player with the ball at the foot, if his position is not conducive to shooting or his ball is about to be steals by the other players, it is best to get the ball out, here the ball is equivalent to the message.
Programme one:
1 |
+ (BOOL)resolveInstanceMethod:(SEL)sel |
1 |
+ (BOOL)resolveClassMethod:(SEL)sel |
Scenario Two:
1 |
- (id)forwardingTargetForSelector:(SEL)aSelector |
Programme III:
1 |
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector; |
1 |
- (void)forwardInvocation:(NSInvocation *)anInvocation; |
So far everyone has known what the message was forwarded. Let's talk about how these packages are called.
First, the system calls Resolveinstancemethod (of course, if the method is a class method, it calls Resolveclassmethod) and lets you add the implementation for this method yourself.
Let's look at an example:
First, you create an object p for the person class, and then call the Run method of P, noting that the Run method is not write-implemented.
Entering the. m file of the person class, I implemented Resolveinstancemethod this method adds an implementation of the Run method to my person class dynamics. (What is dynamic increase?) In fact, when the program is running, a certain method of a class is added to the implementation. The specific implementation of the above is the void run this C function. )
When external calls [P run], because we do not implement the corresponding method of run, then the system will call Resolveinstancemethod let you do some other operations. (Of course, you can also do nothing, but in this case, I added the implementation dynamically for the Run method.) )
Continue running, the program goes to the part of our C function, so the program does not crash.
Here's a second set of methods, Forwardingtargetforselector, which returns the object you need to forward the message to.
We go on to this example, in order to facilitate the presentation of message forwarding, we have created a new car cars, and implemented the car's Run method.
Now I'm not going to do anything with the resolveinstancemethod of scenario one, calling the parent class method directly. As you can see, the system has come to the Forwardingtargetforselector method, and we now return an instance object of the car class.
Continue running, the program comes to the car class of the Run method, so that we implement the message forwarding.
Continue with our example. If we do not implement Forwardingtargetforselector, the system will call the two methods of scenario three Methodsignatureforselector and Forwardinvocation
Methodsignatureforselector is used to generate the method signature, which is called to the parameter Nsinvocation in Forwardinvocation.
At the beginning we are looking for the error unrecognized selector sent to instance reason, the original is because Methodsignatureforselector this method, because did not find the corresponding implementation method of the run, Therefore, an empty method signature is returned, which eventually causes the program error to crash.
So what we need to do is to create a new method signature, and then call the corresponding signature in forwardinvocation with the object you want to forward, which also implements the message forwarding.
About the type of signature generated [email protected]: "explain. Each method hides two parameters by default, self, _cmd,self represents the method caller, _cmd represents the SEL for this method, the signature type is used to describe the return value of the method, the parameter, and V represents the return value of void,@ for self, representing _cmd.
Now we go back to the beginning, we call the person class's Run method, and the final method is accepted by the object of the car class. This is the message forwarding mechanism of OC.
OBJECTIVE-C message Forwarding