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 toobjc_msgSendAnd so on, toobjectSend a message;
  • throughobjc_objecttheisaFind its class;
  • To detect theSELWhether to ignore; For example, ARC ignores operations such as retain.
  • Test if target is nil; If so, ignore it;
  • Looking for from the cacheSEL; Once found, executeSELThe correspondingIMP;
  • If not, then tomethodListsIn looking for;
  • If not, go tosuperclassLook for it. Keep lookingNSObject;
  • If not, enter dynamic method parsing.