IOS SEL (@selector) Principles and Usage Summary (ii)

Source: Internet
Author: User

How the SEL messaging mechanism works

Refer to the following article:

As we mentioned before, a class is like a C structure. NSObject declares a member variable: ISA. Because NSObject is the root class for all classes, all objects will have a member variable for ISA [public inheritance]. The ISA variable points to the class of the object (Figure 3.15) [class is also an entity in objective-c because of the presence of objective-c All classes in the running environment will have their own storage space. Objective-c The running environment allocates space for each class. ISA, which is referred to here, is the space that points to such a class. This establishes the correspondence between classes and objects.] The class space contains the member variables defined by the class, as well as the method implementation, and also contains pointers to their own parent class space.

The selector method is indexed as an index. The data type of the selector is sel. Although the SEL is defined as char*, we can think of it as an int. The name of each method corresponds to a unique int value. For example, method AddObject: probably corresponds to 12. When looking for this method, use selector instead of the name @ "AddObject:"

OBJECTIVE-C data structure, there is a name-selector mapping table 3.16

At compile time, whenever there is a method call, the compiler will look through selector, so (assuming AddObject's selector is 12)

will be compiled into

Objc_msgsend (MyObject, yourobject);

Here, the Objec_msgsend () function will use the MYOBJEC Isa pointer to find MyObject's class space structure and find the corresponding method for selector 12 in the class space structure. If not found, a pointer to the parent class will be used to locate the parent class space structure. Search for selector 12. If it is still not found, continue to find the parent class until it is found and will throw an exception if it is still not found in the root class NSObject.

We can see that this is a very dynamic look-up process. The structure of the class can be changed at run time, which makes it easy to extend the functionality [Objective-c language is dynamic and supports dynamic binding.

Look again

Objective-c How to get the message in a detailed article

objective-c Get message Working principle is this article to introduce the content, look at name mangling time, also talked about objective-c name mangling, So again read a bit objective-c 2.0 programming language and objective-c 2.0 Runtime Reference related content, self-induction.

Put a piece of code first:

[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

Then, let's analyze the above code in detail:

Such a declaration in the OBJC class-(void) foo: (int) A; called method), where it is called: [Theclass foo:10]; it is called a send message. Specifically, send foo: Message to the object Theclass, notice the ":" Behind Foo, which is also part of the message name, the front '-' represents the instance method, and ' + ' represents the class method. A similar statement, in C or C + +, is often called a call function, and in OBJC, the term function is seldom used, not it does not exist, but it is hidden by the OBJC runtime.

As mentioned earlier, OBJC is working with a messaging mechanism, but in fact, a statement such as-(void) foo: (int) A is replaced by Objc_msgsend (RECEIVER,SELECTOR,ARG1,ARG2,....) at compile time. So actually every code that sends a message is essentially a call function, but they call the same function objc_msgsend (or Objc_msgsend_stret (the return value is a struct), Objc_msgsend_ Fpret (return value is floating point type), etc.)

Analyze the parameters of the Objc_msgsend, the first receiver type is the ID, representing the object that accepts the message, the second is the method that selector represents the receiving object, followed by the parameter of the method, which was replaced by the compiler of the previous statement:

[Theclass Foo:10], objc_msg (Theclass, @selector (foo:), 10);

Because both the accepted object and the method of accepting the object are parameterized, the method of accepting and accepting objects can be dynamic at runtime!

For example, the program can be written like this:

id helper = getTheReceiver();  SEL request = getTheSelector();  [helper performSelector:request];

Its implementation is based on the OBJC runtime. The NSObject class implements this mechanism, so every class that inherits from NSObject can automatically get runtime support. In such a class, there is an Isa pointer to the data structure body defined by the class, which is created by the compiler at compile time for the class (which must inherit from NSObject). In this struct there is a pointer to its parent class definition and Dispatch table. Dispatch table is a table of SEL and IMP correspondence.

For methods with the same name, they all have the same SEL, the name of the method does not include the class name, so the subclass and the parent class have the same sel, but their implementations can vary, so the imp corresponding to the SEL in their respective dispatch table is different, IMP is a function pointer, and although each SEL corresponds to the name of a method, the SEL itself is an integral type, given the efficiency, and the compiler generates a separate table for the SEL and method names. With such a structure, OBJC can achieve polymorphism. Or this line of code:

[Theclass Foo:10];

is sent to the Theclass foo: message, then first in the Theclass class structure of the dispatch table to find whether the corresponding SEL, if any, it means that Theclass has a way to respond to the message, The program jumps to the code address header (specified by imp) of the method and begins execution. If the corresponding SEL is not found in the Theclass dispatch table, then the parent class pointer is included in the struct that Isa refers to, and if it is not found at the end, the runtime will appear. Error. So, even if Theclass and its parent are not defined-(void) foo: (int) A method, the program can still be compiled, but if you use Xcode, the compiler will have a warning that theclass may not be able to respond to the message. The reason for not making an error is that the class method can also be created at execution time! The above code:

class_addMethod([MyClassclass], @selector(dynGeneratedMethod:),(IMP)myClassIMP,”[email protected]:i”);

就是给MyClass类在执行时刻增加了一个响应dynGeneratedMethod:消息的方法,这样之后对任何MyClass的instance类 发送dynGeneratedMethod:消息,就会得到响应了.myClassIMP是类收到该消息时要调用的方法,其声明如下:

voidmyClassIMP(id _rec, SEL _cmd, inttheInt)

The first two parameters of this method are required, and then the parameters are the ones we actually use, the number is the same as the number of colons in @selector (), and the number of colons represents the number of arguments. The first parameter is the accepted object of the message, is an instance of MyClass, and the second parameter is the specific message represented by the SEL.

The last parameter of Class_addmethod is the return value and parameter information that represents Dyngeneratedmethod: But I have tried it myself and this parameter does not work.

Several points:

1. For C in the place called function and function call, in OBJC is called method and send message. Attempting to invoke an undefined method results in a compilation error, and a message is sent to the Even if no class defines the method that responds to the message, the compile time does not error, semantically this is also true, a message is not required to be a certain response, but if there is no class can respond to the code to send the message, there will be runtime error, In order to avoid this kind of thing, it can be detected first, so write

if ( [myClass respondsToSelector:@selector(foo:)])      [myClass foo:10];  }

I feel like OBJC. The definition of sender receiver is more focused on the concept of object-oriented. A class is a receiver, and if a method is defined, it can receive a message with the same name as the method. If you use the client (sender) of the class, you try to send a message to the class. If it matches, jump to the method of the class to execute.

2, the method name is such as Foo:, does not include the return type, the parameter type, but also because one foo: corresponds to a sel, so said OBJC does not support the same foo: there are different return types, also does not supports overloading. 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 the method of the class can be run time to create, the class itself can also be created at run time, the previous reference to inherit from the NSObject class, the compiler will help to generate OBJC runtime required class structure definition, as long as we in the Code also follow that structure to create their own class, The same can be achieved with OBJC runtime support.

http://blog.csdn.net/fengsh998/article/details/8614486

IOS SEL (@selector) Principles and Usage Summary (ii)

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.