Sel selector (2)

Source: Internet
Author: User

What is the working principle of the SEL message mechanism?

Reference the following article:

 

As we mentioned earlier, a class is like a C structure. nsobject declares a member variable: ISA. because nsobject is the root class of all classes, all objects will have an ISA member variable [Public inheritance]. the ISA variable points to the class of the object (Figure 3.15) [the class is also an entity in objective-C, all classes in the objective-C runtime environment have their own storage space. the objective-C Runtime Environment allocates space for each class. the ISA mentioned here points to the space of such a class. to establish the correspondence between classes and objects.] the class space contains the member variables defined by the class and the implementation of the method. It also contains pointers to its parent class space.

 

 

The method uses selector as the index. the selector data type is Sel. although SEL is defined as char *, we can think of it as Int. each method name corresponds to a unique int value. for example, the method addobject may correspond to 12. this method uses selector instead of @ "addobject :"

In the Objective-C data structure, a name-Selector ing table 3.16 exists.

 

 

During compilation, the compiler will use selector to find any method call. (assume that the selector of addobject is 12)

 [myObject addObject:yourObject]; 

Will be compiled

Objc_msgsend (myobject, 12, yourobject );

Here, the objec_msgsend () function will use the ISA pointer of myobjec to find the class Space Structure of myobject and find the method corresponding to selector 12 in the class space structure. if not, the pointer pointing to the parent class is used to find the space structure of the parent class for selector 12. if it is still not found, continue to the parent class of the parent class until it is found. If it still cannot be found in the root class nsobject, an exception will be thrown.

We can see that this is a very dynamic search process. the class structure can be changed during running, so that function expansion can be easily performed. [objective-C is a dynamic language and supports dynamic binding.

 

Let's take a look.

How objective-C gets messages

Objective-CObtainMessageThe working principle 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:

 

[Plain]View plaincopy
  1. Myclass. h
  2. @ Interface myclass: nsobject
  3. {
  4. }
  5. @ End
  6. Myclass. m
  7. # Import
  8. # Import "myclass. h"
  9. Void myclassimp (ID _ rec, Sel _ cmd, int theint)
  10. {
  11. Nslog (@ "dynamic added method: % d", theint );
  12. }
  13. -(ID) Init
  14. {
  15. If (Self = [Super init])! = Nil)
  16. {
  17. Class_addmethod ([myclass class], @ selector (dyngeneratedmethod :), (IMP) myclassimp, "[email protected]: I ");
  18. }
  19. Return self;
  20. }
  21. Main. c
  22. # Import "myclass. h"
  23. Int main (INT argc, char * argv [])
  24. {
  25. Myclass theinstance = [[myclass alloc] init];
  26. [Theinstance dyngeneratedmethod: 10];
  27. Return 0;
  28. }

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

 

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, ....) Therefore, in essence, the call function is called for each message sending code ), however, they call the same function objc_msgsend (or objc_msgsend_stret (the returned value is the structure), objc_msgsend_fpret (the returned value is the floating point type), and so on)

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:

[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:

id helper = getTheReceiver();  SEL request = getTheSelector();  [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 the class (which must be inherited from nsobject) during compiler compilation. 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:

[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) of this method 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:

class_addMethod([MyClassclass], @selector(dynGeneratedMethod:),(IMP)myClassIMP,”[email protected]: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:

voidmyClassIMP(id _rec, SEL _cmd, inttheInt)

 

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 such a problem, you can first check and write

if ( [myClass respondsToSelector:@selector(foo:)])      [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. The client (sender) of this class is used to send messages to this class. If the match is found, it will jump to the class 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.

Sel selector (2)

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.