Introduction to the message forwarding mechanism

Source: Internet
Author: User
Tags uikit

I. When is the message forwarding mechanism sent?

Solution: When an object receives a message that cannot be interpreted, the message forwarding mechanism is started, and the programmer can tell the object how to handle the unknown message by this procedure.

Example:-[__nscfnumber lowercasestring]: Unrecognized selector sent to instance 0x87

This exception is thrown by NSOBJC's "Doesnotrecognizeselector" method, which indicates that the message receiver is of type _ _nscfnumber, and that the recipient cannot understand the selector named LowerCaseString.

Two. Why should I use message forwarding?

Solution: 1. Obj-c used to be a variety of happy, such as now there is a case: there is a class, we want it to respond to a message, but this class does not have a corresponding method, and you can not rewrite/inherit this class. At this point, we might think, can you dynamically add a method to a class? Thanks to Obj-c, it takes just a few steps to achieve it.

2. When using @property definition, with @dynamic implementation, will use the message to forward.

3. When a method is not implemented, a message forwarding mechanism is invoked.

Before call:

 .-Geneva- - xx: to:42.074messageforwarding[927:70955]-[messageforwarding running]: Unrecognized selector sent to instance0x7fee615169c0 .-Geneva- - xx: to:42.076messageforwarding[927:70955] * * * * terminating app due to uncaught exception'nsinvalidargumentexception', Reason:'-[messageforwarding running]: Unrecognized selector sent to instance 0x7fee615169c0'FirstThrowCall stack: (0Corefoundation0x00000001106dfe65__exceptionpreprocess +1651LIBOBJC. A.dylib0x0000000110158debObjc_exception_throw + -2Corefoundation0x00000001106e848d-[nsobject (NSObject) Doesnotrecognizeselector:] +2053Corefoundation0x000000011063590a___forwarding___ +9704Corefoundation0x00000001106354b8_cf_forwarding_prep_0 + -5Messageforwarding0x000000010fc590d3-[viewcontroller Viewdidload] + About6UIKit0x0000000110c22f98-[uiviewcontroller Loadviewifrequired] +11987UIKit0x0000000110c232e7-[uiviewcontroller View] + -8UIKit0x0000000110af9ab0-[uiwindow Addrootviewcontrollerviewifpossible] + A9UIKit0x0000000110afa199-[uiwindow _sethidden:forced:] +282TenUIKit0x0000000110b0bc2e-[uiwindow Makekeyandvisible] + the OneUIKit0x0000000110a84663-[uiapplication _callinitializationdelegatesformainscene:transitioncontext:] +4131 AUIKit0X0000000110A8ACC6-[uiapplication _runwithmainscene:transitioncontext:completion:] +1760 -UIKit0x0000000110a87e7b-[uiapplication Workspacedidendtransaction:] +188 -Frontboardservices0x000000011345b754-[fbsserialqueue _performnext] +192 theFrontboardservices0x000000011345bac2-[fbsserialqueue _performnextfromrunloopsource] + $ -Corefoundation0x000000011060ba31__cfrunloop_is_calling_out_to_a_source0_perform_function__ + - -Corefoundation0x000000011060195c__cfrunloopdosources0 +556 -Corefoundation0x0000000110600e13__cfrunlooprun +867 +Corefoundation0x0000000110600828Cfrunlooprunspecific +488 -UIKit0X0000000110A877CD-[uiapplication _run] +402 +UIKit0x0000000110a8c610Uiapplicationmain +171 AMessageforwarding0x000000010fc59a1fMain +111 atLibdyld.dylib0x0000000112e1b92dStart +1) libc++abi.dylib:terminating with uncaught exception of type NSException

After the call:

22.577 -xx: messageforwarding[950: 73397] message. string= Kun kun, message.number=, message.date=2033-08 :£ º +0000

Three. What is the process of message forwarding?

1. Process

Solution: The first stage: first consult the receiver, the class to see if it can dynamically add methods to deal with the current "unknown selector" (unknown selector) This is called dynamic Method Resolution (resolution).

Phase II: Involving "complete message forwarding mechanism" (full forwarding mechanism) if the run-time system has completed the first phase, then the recipient cannot respond to the message containing the selector in a dynamically new way. At this point, the runtime system requests the recipient to handle the message-related method calls in other ways. This breaks down two small steps, first, ask the recipient to see if there are any other objects that can handle the message. If so, the run-time system will

Transfer the message to the object, and the message is forwarded to the end, as usual. Without the "replacement Recever", the full message forwarding mechanism is initiated, and the runtime system encapsulates all the details related to the message into the Nsinvocation object, giving the receiver the last chance to Make it try to resolve the message that is not currently being processed.

2. The method is as follows:

+ (BOOL) Resolveinstancemethod: (SEL) sel;

The parameter of the method is the unknown selector, and its return value is Boolean, indicating whether the class can add an instance method to handle this selector.

If the method that has not been implemented is not an instance method but a class method, then the runtime system calls another method, which is similar to the + (bool) Resolveinstancemethod: (SEL) SEL is called: + (BOOL) Resolveclassmethod :(sel) sel.

3. Conditions of Use

The implementation of the relevant method code has been written, just waiting for the runtime to plug in the dynamic in the class. This scenario is commonly used to implement @dynamic properties, such as the ability to access Nsmanagedobjects object properties in the CoreData framework, because the access methods required to implement these properties can be determined at compile time.

4. Code Advance

The following code shows how to implement the @dynamicnt property with "Resolveinstancemethod:".

#import<Foundation/Foundation.h>@interfaceMessageforwarding:nsobjectIDAutodictionarygetter (IDSelf,sel _cmd);//Setter MethodvoidAutodictionarysetter (IDSelf,sel _cmd,IDValue);//Getter Method/** * Dynamic parsing method * * @param sel Unknown Selector * * @return If this class can add an instance method to handle this selector*/+(BOOL) Resolveinstancemethod: (SEL) sel; @property (nonatomic, strong) NSString*string; @property (nonatomic, strong) NSNumber*Number ; @property (nonatomic, strong) NSDate*date; @property (nonatomic, Strong)IDOpaqueobject;@end#import "MessageForwarding.h"#import<objc/runtime.h>@interfacemessageforwarding () @property (nonatomic, strong) Nsmutabledictionary*Backingstore;@end@implementationmessageforwarding@dynamicstring, Date,number,opaqueobject;#pragmaMark Getter and setterIDAutodictionarygetter (IDSelf,sel _cmd) {        //Get The backing store from the objectMessageforwarding *typeself = (messageforwarding *) Self; Nsmutabledictionary*backingstore =Typeself.backingstore; //The key is simply the selector nameNSString *key =Nsstringfromselector (_cmd); //return the value    return[Backingstore Objectforkey:key];}voidAutodictionarysetter (IDSelf,sel _cmd,IDvalue) {        //Back the backing store from the objectMessageforwarding *kunkunself = (messageforwarding *) Self; Nsmutabledictionary*backstore =Kunkunself.backingstore; /** The selector will is for example, "Setopaqueobject"//With this selector for example, "setopaqueobject" We need to remove the "set" , ":" and lowercase the first//We must remove the set and: and the initial letter of the lowercase letters of the the remainder*/NSString*selectorstring =Nsstringfromselector (_cmd); Nsmutablestring*key =[selectorstring mutablecopy]; //Remove the:at the end//in the last delete:[Key Deletecharactersinrange:nsmakerange (Key.length-1,1)]; //Remove the "set" prefix[Key Deletecharactersinrange:nsmakerange (0,3)]; //lowercase The first characterNSString *lowercasefirstchar = [[Key substringtoindex:1] lowercasestring]; [Key Replacecharactersinrange:nsmakerange (0,1) Withstring:lowercasefirstchar]; if(value) {[Backstore setobject:value forkey:key]; }Else{[Backstore removeobjectforkey:key]; }}#pragmainit-(instancetype) init{if(self =[Super Init]) {_backingstore=@{}.mutablecopy; }    returnSelf ;}#pragmaMark message forwarding messages forwarding mechanism +(BOOL) Resolveinstancemethod: (SEL) sel{//message into a stringNSString *selectorstring =nsstringfromselector (SEL); //if (/**selector is from a @dynamic property*/) {        if([selectorstring Hasprefix:@"Set"]) {Class_addmethod (Self,sel, (IMP) Autodictionarysetter,"[Email protected]:@"); }Else{Class_addmethod (self, SEL, (IMP) Autodictionarygetter,"@@:"); }    returnYES; //  }//    //return [Super Resolveinstancemethod:sel];}@end

5. Recipients of redundancy

The current recipient has a second chance to handle the unknown selector, and in this step, the runtime system will ask: Can you forward this message to other recipients for processing, as follows:

/* * * The  recipient of the redundancy is called when it is not processed for the first time. Resolveinstancemethod: (SEL) SEL, please note that we are unable to manipulate the message forwarded by this step, and if you want to modify the message content before sending it to the recipient of the redundancy, Then you have to do it through the full message forwarding mechanism. * *  @param aselector Message * *  */

6. Complete message forwarding

-(ID) forwardingtargetforselector: (SEL) aselector; /* * *  full message forwarding, when triggering a Nsinvocation object, the "Message dispatch system" (Messages dispatch systems) will personally take the message and assign it to the target  object **/

The whole process of message forwarding

Resolveinstancemethod-> returns YES--the message has been processed

Forwardingtargetforselector---receive the corresponding value---> Message processed

--Return nil-->forwardinvocation--message processed

---> Messages not processed

Introduction to the message forwarding mechanism

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.