Explanation of Objective-C message Acquisition Mechanism

Source: Internet
Author: User

Objective-CObtainMessageThe working mechanism is the content to be introduced in this article.Objective-CName mangling, so I read it again.Objective-C2.0 programming Language andObjective-C2.0 summarize the relevant content in the Runtime Reference.

First paste a piece of code:

 
 
  1.    MyClass.h  
  2.    @interface MyClass : NSObject  
  3.    {  
  4.     }  
  5.    @end  
  6.    MyClass.m  
  7.    #import </usr/include/objc/runtime.h> 
  8.    #import “MyClass.h”  
  9.    void myClassIMP(id _rec, SEL _cmd, int theInt)  
  10.    {  
  11.       NSLog(@”dynamic added method:%d”,theInt);  
  12.    }  
  13.    
  14. - (id)init  
  15. {  
  16.     if( ( self = [super init]) != nil )  
  17.     {  
  18.    class_addMethod([MyClass class], @selector(dynGeneratedMethod:),(IMP)myClassIMP,”v@:i”);  
  19.      }  
  20.     return self;  
  21. }  
  22.  
  23. Main.c  
  24. #import “MyClass.h”  
  25. int main(int argc, char *argv[])  
  26. {  
  27.   MyClass theInstance = [[MyClass alloc] init];  
  28.   [theInstance dynGeneratedMethod:10];  
  29.  return 0;  

The result of this code execution is output on the console:

 
 
  1. dynamic added method:10 

Next, let's analyze the above Code in detail:

In the ObjC class, such a declaration-(void) foo :( int) a; is called a method, and where it is called: [theClass foo: 10]; it is called sending message. Specifically, it sends foo: message to the theClass object. Note that ":" is next to foo, which is also part of the message name, the '-' At the beginning indicates the instance method, and '+' indicates the class method. Similar statements are usually called call functions in C or C ++. In ObjC, the term function is rarely used, not does not exist, it is hidden by the ObjC runtime.

As mentioned above, ObjC works by message mechanism, but in fact the statements such as-(void) foo :( int) a are compiled by objc_msgSend (separator er, selector, arg1, arg2, ....) So in fact, the code for sending each message basically calls the call function. However, they call the same function objc_msgSend or objc_msgSend_stret (the return value is a struct ), objc_msgSend_fpret (Return Value: floating point type)

Analyze the objc_msgSend parameter. The first receiver type is id, which indicates the object that receives the message. The second type is selector, which indicates the method of receiving the object, followed by the parameter of this method, the previous statement is replaced by the compiler:

 
 
  1. [theClass foo:10]  -> objc_msg(theClass,@selector(foo:),10); 

BecauseMessageThe methods of the Acceptance object and the acceptance object are parameterized, so the methods of the Acceptance object and the acceptance object can be dynamic at the runtime!

For example, you can write in the program as follows:

 
 
  1. id helper = getTheReceiver();  
  2. SEL request = getTheSelector();  
  3. [helper performSelector:request]; 

Its implementation is based on the ObjC runtime. NSObject class to implement this mechanism, so every class inherited from NSObject can automatically obtain runtime support. In such a class, there is an isa pointer pointing to the data struct defined by this class. This struct is created by NSObject when the compiler compiles it. this struct contains pointers to its parent class definition and Dispatch table. dispatch table is a table corresponding to SEL and IMP.

For methods with the same name, they all have the same SEL. The method name does not include the class name. Therefore, the subclass and the method with the same name in the parent class have the same SEL, however, their implementations can be different, so the IMP corresponding to SEL in their respective Dispatch tables is different, and IMP is a function pointer, although each SEL corresponds to a method name, considering the efficiency, SEL itself is an integer, the compiler will generate another table corresponding to the SEL and method name. With this structure, objc can achieve polymorphism. Or this line of code:

 
 
  1. [theClass foo:10]; 

If the foo: message is sent to theClass, check whether there is a corresponding SEL in the Dispatch table of the theClass class structure. If so, theClass has a method to respond to the message, the program jumps to the Code address header specified by IMP to start execution. If the corresponding SEL cannot be found in the Dispatch table of theClass, the parent class pointer contained in the structure referred to by isa will be searched for in the parent class, if not found at the end, a runtime error occurs. therefore, even if theClass and its parent class do not define-(void) foo :( int) a method, the program can still be compiled, but if xcode is used, the compiler has a warning that theClass may not be able to respond to the message. No error is reported because the class method can also be created during execution! The above code:

 
 
  1. class_addMethod([MyClass class], @selector(dynGeneratedMethod:),(IMP)myClassIMP,”v@:i”); 

The MyClass class is added with a method to respond to the dynGeneratedMethod: message at the execution time, so that the dynGeneratedMethod: message will be sent to any instance class of MyClass, and the response will be returned. myClassIMP is the method that the class calls when receiving the message. Its declaration is as follows:

 
 
  1. void myClassIMP(id _rec, SEL _cmd, int theInt) 

The first two parameters of this method are required. The following parameters are actually used. The number is the same as the number of colons in @ selector (). The number of colons represents the number of parameters. The first parameter is the message receiving object, which is an instance of MyClass, and the second parameter is the specific message represented by SEL.

The last parameter of Class_addMethod is the return value and parameter information of dynGeneratedMethod:. However, I tried it myself and this parameter does not work.

Key points:

1. For functions called functions and function calls in C, they are called methods and send messages in ObjC ). an attempt to call an undefined method will cause a compilation error and send a message. Even if no class defines a method to respond to the message, no error will be reported during compilation, in terms of semantics, this is also true. When sending a message, no response is required. However, if no class can respond when executing the code for sending the message, a runtime error occurs. To avoid this kind of problem, you can first check and write it as follows:

 
 
  1. if( [myClass respondsToSelector:@selector(foo:)])  
  2. {  
  3.    [myClass foo:10];  

I feel that the definition of a set of sender uploer such as ObjC pays more attention to the object-oriented concept. A class is a receiver. If a method is defined, messages with the same name can be received. When the class's client (sender) is used, the system tries to send messages to the class. If it matches, it will jump to the class's method for execution.

2. The method name is such as foo:, which does not include the return type and parameter type. Because a foo: corresponds to a SEL, ObjC does not support the same foo: there are different return types, and reload is not supported. However, class methods and instance methods can have the same name, but different types of parameters and return types, because they are not in the same dispatch table.

3. Not only can classes be created at runtime, but classes can also be created at runtime. The class inherited from NSObject is mentioned earlier. The compiler will help generate the class structure definition required by ObjC runtime, as long as we create our own class according to the structure in the code, we can get support for ObjC runtime.

Summary: DetailsObjective-CObtainMessageThe work mechanism has been introduced.Objective-COfMessageThe Mechanism shows that it is a flexible language. Finally, I hope this article will help you!

Related Article

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.