runtime abbreviation. is the system at the time of the operation of some mechanism, the most important is the message mechanism. For the C language, the function's call will decide which function to call at compile time (see here for the C-language function call). The sequence executes directly after compilation, without any ambiguity. The function call of OC becomes a message sent. belongs to the dynamic call procedure. It is not possible at compile time to decide which function to actually call (it turns out that OC can call any function during the compile phase, even if the function is not implemented, as long as it is declared without an error.) C language will be in the compilation phase error). The corresponding function will be called based on the name of the function only when it is actually running.
How does OC implement dynamic invocation? Let's take a look at how OC achieves the secret of dynamic calls by sending messages. If you write such a code in OC:
Where obj is an object and Maketext is a function name. For such a simple invocation. Runtime at compile time will convert the above code into
1 |
objc_msgSend(obj,@selector(makeText)); |
First, let's take a look at the Obj object, which is inherited from NSObject in iOS.
123 |
@interface NSObject <nsobject> { Class isa OBJC_ISA_AVAILABILITY; }</nsobject> |
There is a class Isa pointer in the NSOBJCET. Then we look at class:
1234567891011121314 |
typedef struct objc_class *Class;
struct objc_class {
Class isa;
// 指向metaclass
Class super_class ;
// 指向其父类
const char *name ;
// 类名
long version ;
// 类的版本信息,初始化默认为0,可以通过runtime函数class_setVersion和class_getVersion进行修改、读取
long info;
// 一些标识信息,如CLS_CLASS (0x1L) 表示该类为普通 class ,其中包含对象方法和成员变量;CLS_META (0x2L) 表示该类为 metaclass,其中包含类方法;
long instance_size ;
// 该类的实例变量大小(包括从父类继承下来的实例变量);
struct objc_ivar_list *ivars;
// 用于存储每个成员变量的地址
struct objc_method_list **methodLists ;
// 与 info 的一些标志位有关,如CLS_CLASS (0x1L),则存储对象方法,如CLS_META (0x2L),则存储类方法;
struct objc_cache *cache;
// 指向最近使用的方法的指针,用于提升效率;
struct objc_protocol_list *protocols;
// 存储该类遵守的协议
}
|
As we can see, there are a lot of things in a class, and here's a one by one explanation:
Class Isa: Point to Metaclass, which is the static class. In general, ISA in an Obj object points to the normal class, which stores ordinary member variables and object methods (the "-" method at the beginning of the "-"), the ISA pointer in the normal class to the static class, and the static class that stores statically type member variables and class methods (" + "starts with the method).
Class Super_class: Points to the parent class, or null if the class is a root class.
The following picture is a good description of the inheritance relationship of classes and objects:
Note : All metaclass in the ISA pointer are pointed to the metaclass. And the metaclass point to itself. Root Metaclass is generated by inheriting the root class. is consistent with the root class struct member, which is the structure mentioned earlier. The difference is that the ISA pointer to root metaclass points to itself.
The rest of the class is not explained here, so let's take a look at the following:
@selector (Maketext): This is an Sel method selector. The main function of SEL is to quickly find the corresponding method's function pointer by means of the method name (Maketext), and then call its function. The SEL itself is an address of type int, with the name of the method stored in the address. For a class. Each method corresponds to an sel. So there cannot be 2 identical methods in the iOS class, even if the parameter types are different because the SEL is generated from the method name, the same method name can only correspond to one sel.
Let's take a look at how the specific message is sent after it's been dynamically searched for the corresponding method.
First, the compiler converts the code [obj Maketext] into objc_msgsend (obj, @selector (Maketext)), in the Objc_msgsend function. The class of obj is first found through the ISA pointer of obj. In class, first go to the cache through the SEL to find the corresponding function method (guess the Cache method list is the SEL key through the hash table to store, this can improve the function lookup speed), if not found in the cache. Again to find in the methodlist, if not found in MethodList, then take superclass to find. If found, the method is added to the cache to facilitate the next lookup, and the function pointer in method jumps to the corresponding function to execute.
Objective-c the whole runtime thing. (a) message mechanism