RunTime
RunTime is short for RunTime. Is the system at the time of the operation of some mechanisms, the most important is the message mechanism.
Two important features of the RunTime
- In languages like C++, it’s determined at compile time, and runtime is finding where memory is and executing code; In Objective-C, methods are actually called in a way called “message forwarding,” which tells class/ Object THAT I’m going to call a method of some object/class; But! Whether and how a method is called can be determined and modified at run time.
- The class/object/method… Are structs in nature, and therefore can be modified at run time.
Class
Let’s look at the definition of Class:
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
Copy the code
Class is actually objc_class
objc_class
In
, you can find a struct called objc_class. So let’s look at the definition of this struct
struct objc_class {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
#if ! __OBJC2__Class _Nullable super_class OBJC2_UNAVAILABLE; const char * _Nonnull name OBJC2_UNAVAILABLE; long version OBJC2_UNAVAILABLE; long info OBJC2_UNAVAILABLE; long instance_size OBJC2_UNAVAILABLE; Struct objc_iVAR_list * _Nullable ivars OBJC2_UNAVAILABLE; struct objc_iVAR_list * _Nullable ivars OBJC2_UNAVAILABLE; Struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE; struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE; Struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE; // Protocols struct objc_PROTOCOL_list * _Nullable protocols OBJC2_UNAVAILABLE;#endif
} OBJC2_UNAVAILABLE;
Copy the code
Normally when we define a class, it actually gets compiled into a struct like this; The variables that we define, the methods, and so on, are stored in structs.
objc_object
/// Represents an instance of a class.
struct objc_object {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};
Copy the code
When we create an instance of a class, we actually generate a struct like this. The Class ISA in it can find the corresponding Class when the message is forwarded
objc_method_list
Take a look at the objc_method_list definition in objc_class
struct objc_method_list {
int method_count;
/* variable length structure */
struct objc_method method_list[1];
}
Copy the code
Objc_method_list stores an objc_method
objc_method
struct objc_method {
SEL method_name;
char *method_types;
IMP method_imp;
}
Copy the code
This objc_method is the familiar method. As you can see, method is mainly composed of method name, function pointer, SEL and IMP mapping
SEL
typedef struct objc_selector *SEL;
Copy the code
Objc_selector is just a C string. Therefore, SEL is actually a string, which can be understood as the hash of the other method name
IMP
typedef void (*IMP)(void /* id, SEL, ... */ );
Copy the code
IMP is a concrete implementation of a method
When we call a method, we send a “message” to the object containing the method name and parameters. Use ISA to find objc_class, then traverse the objc_class to find the corresponding objc_method, and then call IMP. That is, the method name SEl and the actual implementation code IMP are bound by objC_method, which makes them relatively dynamic.
The specific flow of message passing
- Convert the method call to
objc_msgSend
And so on, toobject
Send a message; - through
objc_object
theisa
Find its class; - To detect the
SEL
Whether to ignore; For example, ARC ignores operations such as retain. - Test if target is nil; If so, ignore it;
- Looking for from the cache
SEL
; Once found, executeSEL
The correspondingIMP
; - If not, then to
methodLists
In looking for; - If not, go to
superclass
Look for it. Keep lookingNSObject
; - If not, enter dynamic method parsing.