function Call of iOS development runtime

Source: Internet
Author: User

The article from the Little Wolf's iOS blog, has always felt that Csdn's blog UI is not too good-looking, look at the blog is not very cool, so I built a blog. Welcome to the link to see my blog. Also welcome to add QQ Group to discuss iOS technical issues


After two months of interviews, the work finally settled. During this two-month interview process, I found a lot of ground-based things that big companies value. such as: Runloop,runtime,block and so on. This article mainly introduces the mechanism of function call in runtime, the knowledge point has a certain depth, and is also the embodiment of the ability in the interview process.

function calls in the 1.OBJECTIVE-C

For the C language, the function call is done directly by the compiler, and at compile time the program begins to look for the function to be executed (the principle of C-language function invocation). In OC, we refer to the function call as message sending. The program does not look for functions to execute at compile time, and it must wait until it is really run before the program looks for the function to execute.

Example: in C language, only one function is declared, not implemented. This function is called elsewhere. Compile time will be error (C language compile time to find the function to execute, not found so error). The same situation in OC will not error, only in the run time will be error. (The OC runtime only looks for functions to execute)

The underlying implementation of the 2.OBJECTIVE-C function call

Objective-CThe only function that can be run is to find the functions to be executed mainly due to the runtime SDK. Let's Objective-C take a look at how the program has run-time features.
There is a method under the runtime SDK objc_msgSend()

...)

When we write the next line of code [obj doSth]; , at compile time, the compiler will turn our code into

    objc_msgSend(obj,@selector(doSth));

objc_msgSend()The method implements the function lookup and matching, the following is its principle:

    1. objfinds the list of functions stored in the object class based on the object methodLists .
    2. Then find the @selector(doSth) methodLists corresponding function pointer in the SEL method_imp .
    3. method_impa function that invokes a response based on a function pointer.
Implementation details of the 3.objc_msgsend

Before we just briefly introduced objc_msgSend() the principle, let's take a closer look at objc_msgSend how it is implemented.
First, for any one of the NSObject objects, there is an Isa attribute that points to the class of the object Class

@interface NSObject <NSObject> {    Class isa  OBJC_ISA_AVAILABILITY;}

According to the object call can get the corresponding Class . Now let's see.Class

typedef structObjc_class *class;structObjc_class {class Isa;//point to MetaclassClass superclass;//point to Parent class    Const Char*name;//class nameuint32_tversion;//class version informationuint32_t info;//Some identification information, indicating whether it is a normal class or a metaclassuint32_t instance_size;//The instance variable size of the class (including instance variables inherited from the parent class);    structOld_ivar_list *ivars;//information about member variables in a class    structOld_method_list **methodlists;    Class in the method list cache cache; Find the cache of methods to increase efficiencystructOld_protocol_list *protocols;//Storage of the agreements to which such class complies}

By the above code we can see that Class it is a struct pointer, pointing to the objc_class struct body. A objc_class list of methods is stored in methodLists . So, according to Class us, we can directly findmethodLists
Let's see how to methodLists find the corresponding function pointer from the

struct  old_method_list   {void  *obsolete;    //obsolete attribute  int method_count;    //Method number     /* variable length structure */ struct  //method corresponding to the SEL  char *method_types;    //Method type         IMP Method_imp; //method corresponding to the function pointer };  

For old_method_list structs, he stores the old_method number of methods and the first address of the method. We can think of him as a variable-length old_method array.

At first I don't understand why the method_list[1] size of the array is 1? Later figured out that because the size of the array is variable, different classes correspond to the number of different methods. So when you define it, only the first address is stored, and the length is expanded during actual use.

For old_method The structure, he consists of three members of the Sel,type,imp. So we method_list old_method can get the function pointer imp as soon as we find it in. Here's the code for the lookup:

static  inline Old_method *_f  indmethodinlist (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, passing in old_method_list and SEL , returningold_method
    2. The array is first old_method_list empty, and if empty, nil is returned.
    3. Iterate through the old_method_list array and, depending on SEL the match, findold_method
4. Performance optimizations for function calls

In the above section we have finished the basic procedure of the function call. After reading the above section, you may wonder: Objective-C is the function call so complex that it will cause very slow running? After all, every call to a function has to go through so many processes.
Don't worry, in fact, in the process of calling Apple to do some performance optimization, so that its call is not much more than the C language. Let's take a look at what performance optimizations are being done:

Use of the 4.1 sel

People may have doubts long ago, the front has been saying SEL , what SEL is a thing?

Antypemethod selector.typedef struct objc_selector *SEL;

Apple's official explanation for the SEL is an opaque type, which represents a method selector.
The SEL essence is actually an int type address that points to the stored method name. For each class, a special empty space is allocated that stores the method name in the class, and the SEL is the address that points to the corresponding method name. Because the method name string is unique, the SEL is unique.
Why not use the SEL directly with the method name? This issue did not find more official information, personally think because the method name is a string, sel is an int type, the use of the int type is more convenient, more efficient (especially when comparing equality, the comparison of the string is much less efficient than int)

Use of the 4.2 cache

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

obj->isa->methodListsold_method->method_imp
    1. Because it is a member variable, isa obj methodLists It is a isa member variable, so use obj can get directlymethodLists
    2. Because method_imp it is a old_method member variable, so old_method you can get it directlymethod_imp

So the main time consumed by the function call process is methodLists found in old_method .
cacheis used to optimize the search process.
We can think of cache simplicity as a hash table, key Yes SEL , Value Yes old_method . It is cache quite simple and efficient to find from within old_method .
methodLists old_method The real process of finding from in is divided into the following two steps:

    1. by SEL cache searching in old_method , if you find a direct return, if no execution is found 2
    2. In the Find methodLists old_method , find and then old_method insert cache in order to facilitate the next search, and then returnold_method

As a result, the first call to a function is slower, because cache there is no such function, the second call will be very fast

Summarize

This article is mainly about the Objective-C process of function calls, and other less relevant things are ignored, such as the objc_class structure of other member variables, this class can not find how to find the function in the parent class, if not found what to do? These questions I may follow up also an article introduction, now temporarily first write this. If someone wants to know can ask in the comment area or add QQ group discussion. If you have any objections, you can talk to me.


function Call of iOS development runtime

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.