Runtime Series

Data structure Data structure Message mechanism The nature of super The nature of Super

The outline

The Runtime profile

  • Runtime is one useC, C++, assemblyThe runtime library, including a lot of C language API, encapsulates a lot of dynamic related functions;
  • Objective-c is a dynamic runtime language that allows many operations to be deferred until the program is running.OCThe dynamic nature ofRuntimeTo support and realize,RumtimeIs the heart of it;
  • We usually write itOCThe underlying code is converted toRuntime APICall.

Objective-c is a dynamic runtime language

What is compile-time run time?

  • Compile-time: The compiler compiles the program code into a language that the computer can recognize, with some simple syntax checks;
  • Runtime: Code runs and is loaded into memory, at which point errors can cause the program to crash. Crash:unrecognized selector send to instance/class.

What is the difference between a compile-time language and a dynamic runtime language?

  • Compile-time languages: function resolution at compile time;
  • Dynamic runtime languages: Defer function decisions to runtime.
For example,

For NSString *string = [[NSMutableArray alloc]init];

  • Compile-time: when the compiler performs a type check due to a givenNSStringA pointer to a type is assigned to aNSMutableArrayObject, so the compiler warns about type mismatches. But the compiler will change thatstringAs aNSStringSostringThe objectNSStringThe method compiles without any problems while callingNSMutableArrayMethod, compilation will directly report an error.
  • Runtime: due tostringIt actually points to oneNSMutableArrayObject,NSMutableArrayObjects have nostringByAppendingString:Method, so crash:unrecognized selector send to instance.
    NSString *string = [[NSMutableArray alloc]init];  //⚠️Incompatible pointer types initializing 'NSString *' with an expression of type 'NSMutableArray *'
    [string stringByAppendingString:@"abc"];
    [string addObject:@"abc"];  //❌No visible @interface For 'NSString' declares the selector 'addObject:'
Copy the code

There are two versions of Runtime

  • Legacy (earlier version), corresponding programming interface: Objective-C 1.0, applied to32-bit programs on OS X desktop;
  • Modern (Modern version), corresponding programming interface:Objective – 2.0 C, is applied toIPhone Applications and 64-bit Programs on OS X V10.5 and later.

Objective-c programs interact with the Runtime system at three different levels

  • Through objective-C source code;
  • Methods defined by the NSObject class in the Foundation framework, such as:
// Get a class object based on the instance object or class name
- (Class)class
+ (Class)class
// Check whether the current instance/class object's ISA points to a class/meta-class object or a subclass of it
- (BOOL)isKindOfClass:(Class)cls
+ (BOOL)isKindOfClass:(Class)cls
// Check whether the isa of the current instance/class object refers to the class/meta-class object type
- (BOOL)isMemberOfClass:(Class)cls
+ (BOOL)isMemberOfClass:(Class)cls
// Determine whether an object can receive a particular message
- (BOOL)respondsToSelector:(SEL)sel
+ (BOOL)respondsToSelector:(SEL)sel
// Determine whether an object implements a method defined in a particular protocol
- (BOOL)conformsToProtocol:(Protocol *)protocol
+ (BOOL)conformsToProtocol:(Protocol *)protocol
// The IMP of this method can be obtained according to a SEL
- (IMP)methodForSelector:(SEL)sel
+ (IMP)methodForSelector:(SEL)sel
Copy the code
  • By calling the Runtime function directly, as follows:

related

// Dynamically create a pair of classes and metaclasses (arguments: parent class, class name, extra memory)
Class objc_allocateClassPair(Class superclass, const char *name, size_t extraBytes)
// Register a pair of classes and metaclasses (add member variables before class registration)
void objc_registerClassPair(Class cls) 
Destroy a pair of classes and metaclasses
void objc_disposeClassPair(Class cls)
// Get the Class to which ISA points
Class object_getClass(id obj)
// Set the Class to which isa points
Class object_setClass(id obj, Class cls)
// Determine if an OC object is Class
BOOL object_isClass(id obj)
// Determine whether a Class is a metaclass
BOOL class_isMetaClass(Class cls)
// Get the parent class
Class class_getSuperclass(Class cls)
Copy the code

Member variable correlation

// Get an instance variable
Ivar class_getInstanceVariable(Class cls, const char *name)
// Copy the list of instance variables.
Ivar *class_copyIvarList(Class cls, unsigned int *outCount)
// Sets and gets the values of member variables
void object_setIvar(id obj, Ivar ivar, id value)
id object_getIvar(id obj, Ivar ivar)
// Add member variables dynamically (registered classes cannot add member variables dynamically)
BOOL class_addIvar(Class cls, const char * name, size_t size, uint8_t alignment, const char * types)
// Get information about member variables
const char *ivar_getName(Ivar v)
const char *ivar_getTypeEncoding(Ivar v)
Copy the code

Attributes related to

// Get an attribute
objc_property_t class_getProperty(Class cls, const char *name)
// Copy the property list (call free at the end)
objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)
// Add attributes dynamically
BOOL class_addProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount)
// Dynamically replace attributes
void class_replaceProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount)
// Get some information about attributes
const char *property_getName(objc_property_t property)
const char *property_getAttributes(objc_property_t property)
Copy the code

Methods the related

// Get an instance method, class method
Method class_getInstanceMethod(Class cls, SEL name)
Method class_getClassMethod(Class cls, SEL name)
The // method implements the related operations
IMP class_getMethodImplementation(Class cls, SEL name) 
IMP method_setImplementation(Method m, IMP imp)
void method_exchangeImplementations(Method m1, Method m2) 
// Copy the list of methods (call free at the end)
Method *class_copyMethodList(Class cls, unsigned int *outCount)
// Add method dynamically
BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
// Dynamic replacement method
IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types)
// Get the information about the method (with copy you need to call free)
SEL method_getName(Method m)
IMP method_getImplementation(Method m)
const char *method_getTypeEncoding(Method m)
unsigned int method_getNumberOfArguments(Method m)
char *method_copyReturnType(Method m)
char *method_copyArgumentType(Method m, unsigned int index)
// Selector correlation
const char *sel_getName(SEL sel)
SEL sel_registerName(const char *str)
// use block as a method
IMP imp_implementationWithBlock(id block)
id imp_getBlock(IMP anImp)
BOOL imp_removeBlock(IMP anImp)
Copy the code

Associated object correlation

Portal: OC-association Associated object

// Add the associated object
void objc_setAssociatedObject(id object, const void * key, id value, objc_AssociationPolicy policy)
// Get the associated object
id objc_getAssociatedObject(id object, const void * key)
// Remove all associated objects of the specified object
void objc_removeAssociatedObjects(id object)
Copy the code

What are the applications of Runtime?

  • Add attributes to categories using AssociatedObject
  • Iterate over all member variables of the class (changing placeholder text color of TextField, dictionary conversion model, auto archive unfile)
  • Implementation of switching methods (methods for intercepting switching systems)
  • Use the message forwarding mechanism to resolve exceptions where methods cannot be found
  • .

A link to the

Runtime open-source code maintained by Apple GNU Runtime open-source code maintained by Apple Official documentation Runtime