Analysis of runtime mechanism

Source: Internet
Author: User

Original link:http://www.cnblogs.com/biosli/p/NSObject_inherit_2.html

Objective-c is a dynamic language, a function is composed of a selector (SEL), and a implement (IML). Selector is equivalent to the house number, and implement is the real tenant (function implementation).

And real life, the number can be casually sent (@selector (XXX)), but not necessarily all to find tenants, if not found the system will give the program a few chances to program normal operation, there is no way out to throw an exception. Is the process of finding the SEL's IML when Objc_msgsend is called. Let's take this process as an example to see the very useful functions involved.

First, Resolveinstancemethod function

Prototype:

+ (BOOL) Resolveinstancemethod: (SEL) name

This function is executed at run time (runtime) and does not find the SEL's IML. This function is an opportunity to add functions to the class using Class_addmethod.

According to the documentation, if you implement Add function code, return Yes, and no return is implemented.

Implementation examples:

//Global FunctionsvoidDynamicmethodimp (IDSelf , SEL _cmd) {    //implementation ....}@implementationMytestobject//... ..//class Functions+(BOOL) Resolveinstancemethod: (SEL) asel{if(Asel = =@selector (resolvethismethoddynamically)) {Class_addmethod ([ Selfclass], Asel, (IMP) Dynamicmethodimp,"[email protected]:"); returnYES; }    return[Super Resolveinstancemethod:asel];}//... ..@end

Attention:

According to the demo experiment, this function returns the BOOL value system implementation of the Objc_msgsend function is not referenced, no matter what the system will try to use the SEL again to find the IML, if the function implementation is found to execute the function. If you cannot find another search process to continue.

Second, Forwardingtargetforselector:

Prototype:

-(ID) Forwardingtargetforselector: (SEL) Aselector

The process is here, and the system gives an opportunity to transfer the SEL to other objects.

The return parameter is an object, and if the object is not nil or self, the system will forward the running message to that object for execution. Otherwise, continue to find other processes.

Implementation examples:

//forwarding Target class@interfaceNoneclass:nsobject@end@implementationNoneclass+(void) load{NSLog (@"noneclass _cmd:%@", Nsstringfromselector (_cmd));}- (void) noneclassmethod{NSLog (@"_cmd:%@", Nsstringfromselector (_cmd));}@end@implementationMytestobject//... ..//to turn a message out of an object- (ID) Forwardingtargetforselector: (SEL) aselector{NSLog (@"mytestobject _cmd:%@", Nsstringfromselector (_cmd)); Noneclass*none =[[Noneclass alloc] init]; if([None Respondstoselector:aselector]) {returnnone; }        return[Super Forwardingtargetforselector:aselector];}//... ..@end

When the Execute Mytestobject object executes the [Mytestobject Nonclassmethod] function, the message is thrown into the Noneclass object for execution.

Third, Methodsignatureforselector:

Prototype:

-(Nsmethodsignature *) Methodsignatureforselector: (SEL) Aselector

This function and the following forwardinvocation: Is the last chance to find an IML. This function gives the overloaded party the opportunity to throw a signature of a function, followed by the forwardinvocation: to execute.

Four, Forwardinvocation:

Prototype:

-(void) Forwardinvocation: (nsinvocation *) aninvocation

True execution from Methodsignatureforselector: The returned nsmethodsignature. In this function, nsinvocation can be forwarded to multiple objects several times, which is also a flexible way. (Forwardingtargetforselector can only be turned to an object in the form of selector)

code example:

#import<Foundation/Foundation.h>@interfacebook:nsobject{nsmutabledictionary*data;}//two setter/getter were declared@property (retain) NSString *title: @property (retain) NSString*author;@end @implementationbook@dynamic title, author;//do not automatically generate implementations- (ID) init{if(self =[Super Init]) {Data=[[Nsmutabledictionary alloc] init]; [Data setobject:@"Tom Sawyer"Forkey:@"title"]; [Data setobject:@"Mark Twain"Forkey:@"author"]; }    returnSelf ;} - (void) dealloc{[data release]; [Super Dealloc];} -(Nsmethodsignature *) Methodsignatureforselector: (SEL) selector{nsstring*sel =Nsstringfromselector (selector); if(Sel rangeofstring:@"Set"].location = =0) {        //dynamic creation of a setter function        return[Nsmethodsignature signaturewithobjctypes:"[Email protected]:@"]; } Else {        //dynamic creation of a getter function        return[Nsmethodsignature signaturewithobjctypes:"@@:"]; }} - (void) Forwardinvocation: (Nsinvocation *) invocation{//get the name of the letterNSString *key =nsstringfromselector ([invocation selector]); if([Key rangeofstring:@"Set"].location = =0) {        //setter function shaped like setxxx: Remove set and colonkey = [[Key Substringwithrange:nsmakerange (3, [Key length]-4)] [lowercasestring]; NSString*obj; //find a value from the list of parameters[Invocation getargument:&obj Atindex:2];    [Data setobject:obj Forkey:key]; } Else {        //getter function is relatively simple, directly to the function name as key is good. NSString *obj =[Data Objectforkey:key]; [Invocation Setreturnvalue:&obj]; }} @end
Five, Doesnotrecognizeselector:

Prototype:

-(void) Doesnotrecognizeselector: (SEL) Aselector

As the last step in the implementation of a function, NSObject implements this function with only one function, which is to throw an exception.

Although it is theoretically possible to overload this function implementation to ensure that no exception is thrown (without calling the super implementation), Apple's documentation emphasizes that "it must not be possible for this function to end, it has to throw an exception."

Vi. use of the scene

1, call Resolveinstancemethod give the opportunity to let the class add this implementation of this function

2. Call Forwardingtargetforselector to allow other objects to execute this function

3. Call Methodsignatureforselector (function symbol maker) and forwardinvocation (function executor) to flexibly execute the target function in other form.

If none of the calls Doesnotrecognizeselector throws an exception.

Seven, Respondstoselector

Prototype:

+ (BOOL) Respondstoselector: (SEL) Aselector

This function is more familiar to you, to check whether the object implements a function.

This function is usually not overloaded, but after a dynamic implementation of the lookup process, it is necessary to overload this function to allow the external interface to find the dynamic implementation of the function when the return of Yes, to ensure uniform behavior of the external interface.

code example:

@implementation  Book // ... .. - (BOOL) Respondstoselector: (SEL) aselector{    if (@selector (settitle:) = = Aselector | |          = = Aselector | |          = = Aselector | |          = = aselector)    {        return  YES;    }         return  //... @end

Analysis of the runtime 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.