Function call for developing RunTime in iOS

Source: Internet
Author: User

Function call for developing RunTime in iOS

The article is from Xiao binlang's iOS blog. He has always thought that the blog UI of csdn is not very nice and he is not very good at reading blogs, so he set up a blog by himself. You are welcome to visit my blog at the link. You are also welcome to join the QQ Group to discuss iOS technology issues.


After more than two months of interviews, the work was settled. During the interviews over the past two months, I found that many underlying things are very important to large companies. For example, RunLoop, RunTime, and Block. This article mainly introduces the function calling mechanism in RunTime. The knowledge points are in-depth and reflect the competence in the interview process.

1. function call in Objective-C

For C language, function calls are directly converted by the compiler. during compilation, the program starts to look for the function to be executed (C language function call principle ). In OC, function calling is called message sending. During compilation, the program does not search for the function to be executed. It must wait until the program runs.

Example: in C language, only one function is declared and not implemented. Call this function elsewhere. An error is reported during compilation (the function to be executed is found during C language compilation, so the error is not found ). In the same case, no error is reported in OC, and only an error is reported during running. (Find the function to be executed only when the OC runs)

2. Underlying implementation of Objective-C function calls

Objective-CThe reason why you can find the function to be executed during running is mainly due to the runTime SDK. Let's take a look.Objective-CHow to make the program have runtime characteristics.
There isobjc_msgSend()Method

OBJC_EXPORT id objc_msgSend(id self, SEL op, ...)

When we write down a line of code[obj doSth];During compilation, the compiler will convert our code

    objc_msgSend(obj,@selector(doSth));

objc_msgSend()The method implements function search and matching. The following describes its principle:

  1. Based on the objectobjFind the function list stored in the object classmethodLists.
  2. Then, according to SEL@selector(doSth)InmethodListsFind the corresponding function pointer inmethod_imp.
  3. According to the function pointermethod_impCall the response function. 3. Implementation Details of objc_msgSend

    We just briefly introducedobjc_msgSend()For more information, seeobjc_msgSendIs implemented.
    First, there is an isa attribute under any NSObject object, pointing to the correspondingClassClass

    @interface NSObject 
        
          {    Class isa  OBJC_ISA_AVAILABILITY;}
        

    You can obtain the correspondingClass. Let's take a look.Class

    Typedef struct objc_class * Class; struct objc_class {Class isa; // points to metaclass Class superclass; // points to parent Class const char * name; // Class name uint32_t version; // Class version information uint32_t info; // some identification information, indicating whether it is a common Class or metaclass uint32_t instance_size; // The instance variable size of the class (including the instance variables inherited from the parent class); struct old_ivar_list * ivars; // The information of the member variables in the class struct old_method_list ** methodLists; the method list Cache in the class; the cache of the search method, used to improve efficiency struct old_protocol_list * protocols; // store the protocols that this class complies}

    We can see from the above CodeClassIs a struct pointer pointingobjc_classStruct. Inobjc_classStored inmethodListsMethod list. ThereforeClassWe can findmethodLists
    Next let's take a look at howmethodListsFind the corresponding function pointer

    Struct old_method_list {void * obsolete; // discarded attribute int method_count; // number of methods/* variable length structure */struct old_method method_list [1]; first address of the method }; struct old_method {SEL method_name; // SEL char * method_types corresponding to the method; // method type IMP method_imp; // function pointer corresponding to the method };

    Forold_method_listStruct, which storesold_methodThe number of methods and the first address of the method. We can regard it as a variable-lengthold_methodArray.

    At first, I don't understand whymethod_list[1]How can the array size be 1? Later I figured out that because the array size is variable, different classes correspond to different methods. Therefore, only the first address is stored during definition, and the length is extended during actual use.

    Forold_methodStruct, which consists of three members: SEL, type, and IMP. Therefore, we only needmethod_listFoundold_methodYou can get the function pointer IMP. The following is the search code:

    static inline old_method *_findMethodInList(old_method_list * mlist, SEL sel) {    int i;    if (!mlist) return nil;    for (i = 0; i < mlist->method_count; i++) {        old_method *m = &mlist->method_list[i];        if (m->method_name == sel) {            return m;        }    }    return nil;}
    1. The lookup function is an inline function.old_method_listAndSEL, Returnold_method
    2. Firstold_method_listArray is empty. If it is null, nil is returned.
    3. Traversalold_method_listArray, accordingSELMatch, findold_method4. function call Performance Optimization

      The above section describes the basic process of function calling. After reading the above sections, you may be confused:Objective-CFunction calls are so complex, will it lead to very slow running? After all, every time you call a function, you have to go through so many processes.
      Don't worry. In fact, Apple has made some performance optimization during the call process, so that it does not call much more than the C language. Next, let's take a look at the performance optimizations:

      4.1 Use of SEL

      You may have long been confused.SEL,SELWhat is it?

      /// An opaque type that represents a method selector.typedef struct objc_selector *SEL;

      Apple's official explanation of SEL is: an opaque type, which represents a method selector.
      SEL is actually an int type address, pointing to the name of the stored method. For each class, a special empty space is allocated. The method name in the special storage class, SEL is the address pointing to the corresponding method name. Because the method name string is unique, SEL is also unique.
      Why not use SEL instead of the method name? This problem does not find more official information. I personally think that because the method name is a string and SEL is an int type, int type is more convenient and more efficient (especially when the comparison is equal, string comparison is much less efficient than int)

      4.2 Use of cache

      Let's take a closer look at the function call process:

      obj->isa->methodListsold_method->method_imp
      1. BecauseisaYesobjMember variables,methodListsYesisaSo useobjCan be obtained directlymethodLists
      2. Becausemethod_impYesold_methodSo useold_methodCan be obtained directlymethod_imp

        Therefore, the main time consumed in the function call process ismethodListsSearchold_method.
        cacheIt is used to optimize the search process.
        We cancacheAs a hash table,keyYesSEL,ValueYesold_method. From this we can see thatcacheSearchold_methodRelatively simple and efficient.
        SlavemethodListsSearchold_methodThe real process is divided into the following two steps:

        1. PassSELIncacheSearchold_methodIf no result is found, 2 is returned. If no result is found, 2 is returned.
        2. InmethodListsSearchold_method.old_methodInsertcacheTo facilitate next search and then returnold_method

          It can be seen that the first time a function is called, it will be slow becausecacheWithout this function, the second call will be very fast.

          Summary

          This article focuses onObjective-CIn the function call process, other irrelevant things are ignored, suchobjc_classOther member variables in the struct are used. If no function is found in this class, how can this function be searched in the parent class? What if no function is found? I may introduce these questions in the future. Now I want to write them here. If you want to know, you can ask a question in the comment area or add a QQ Group for discussion. If you have any objection, you can also tell me


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.