2020.03.30

I am just a knowledge porter. In order to prepare for the interview and consolidate my knowledge system, I have simplified and sorted out the knowledge points related to runtime, so as to quickly understand and memorize.

(1) Runtime concept

  1. Runtime is a set of frameworks written in C, C++, and assembly
  2. Objective-c is an extension of C with Runtime as its core
  3. The Runtime makes Objective-C object-oriented and dynamic
  4. At the heart of Runtime is Messaging.

Dynamic characteristics formed by Runtime:

  1. Data types are deferred to runtime determination
  2. Methods defer selection and change to run time

In my personal understanding, the program is to convert our written OC to C at Runtime, and then to computer-recognized assembly language, while converting from OC to C, the Runtime library forms explicit instructions according to the context of our code.

Message mechanism inherits the idea of all objects, treating classes, instance objects, methods and so on as a message instruction: which object, which method is executed, which parameters are attached, the subject, predicate and object sets together to form a complete sentence delivered to the computer.

1.1 Message Passing

OC classes, objects and methods are all structures in nature, which is the unit of an information set. The following concepts are involved in the underlying implementation of OC:

  • Class object (objc_class)
  • Instance (objc_object)
  • The metaclass (Meta Class)
  • Method(objc_method)
  • SEL(objc_selector)
  • IMP
  • Class cache (objc_cache)
  • Category(objc_category)

1.1.1 isa pointer

All instance objects are the same object (objc_object). Id is the same object type, so it can point to all objects. This object has only one pointer isa, which points to the object’s class (objc_class). The structure of aclass object contains ivars, methodLists, etc. The isa pointer of the class object points to the class of the class object, which is called metaclass. In addition, the class object generates instance objects during compilation, which isa singleton, so isa expresses the logical relationship between the class and the instance (see the following figure). Read the end post for details on the underlying code.)

  • The ISA of an instance refers to a class object.
  • The ISA of aclass object refers to metaclass.
  • Metaclass isa points to root metaclass

1.1.2 method

Method is the structure of the Method, which contains SEL, IMP and Method type attribute. Personally, I understand that SEL is the Method index, and IMP is the concrete implementation of the Method.

1.1.3 Class Cache (Objc_Cache) and Category(objc_Category)

Only 20% of a class’s functions are often called, perhaps 80% of the total number of calls. It doesn’t make sense to iterate over objC_method_list once for every message. Function queries can be much more efficient if frequently called functions are cached. This is what objc_Cache, another important member of Objc_class, does. A Category is a pointer to a classification structure, The structure body contains a collection of instanceMethods, classMethods, protocols, instanceProperties, classes to extend (CLS) and class names.

1.2 Message Forwarding

If no method is found during message delivery, the system gives three chances for recovery.

1.2.1 Dynamic Method analysis

First, the objective-c runtime calls +(BOOL)resolveInstanceMethod:(SEL) SEL or +(BOOL) resolveClassMethod:(SEL) SEL, giving you the opportunity to provide a function implementation. If you add the function and return YES, the system will restart the message sending process at runtime. Asks if there are any dynamically added methods for processing.

1.2.2 Alternate receivers

If the target object implementation – (id) forwardingTargetForSelector aSelector: (SEL), the Runtime will call this method at this moment, give you the opportunity to put forward this message to other objects.

1.2.3 Complete Message Forwarding (Message Redirection)

If you could not handle unknown messages in the previous step, the only thing you can do is enable the full message forwarding mechanism. First of all, it will send – methodSignatureForSelector: message function parameters and return values of the type. If – methodSignatureForSelector: returns nil, the Runtime will send – doesNotRecognizeSelector: news, program will hang up now. If a function signature is returned, the Runtime creates an NSInvocation object and sends a -Forward Invocation: message to the target object.

(2) API

  • Objc_msgSend (object, @selector, parameter)
  • Objc_getClass (" class name ", sel): Returns the current class, nil if the class you’re looking for doesn’t exist;
  • Objc_lookUpClass (" class name ", sel): Returns the current class, nil if the class you’re looking for doesn’t exist;
  • Objc_getRequiredClass (" class name ", sel): Returns the current class. If the class you are looking for does not exist, it will flash back. Use with caution.
  • Object_getClass (" class name ", sel): Returns the current class by object
  • class_addMethod([Person class], sel, (IMP)eat, "v@:@"): 1. Class type; 2. Method Number; 3. Method implementation, function pointer; 4. Return value type (c language string), see documentation
  • Ivar *ivars = class_copyIvarList([Person class], &count)
  • const char *name = ivar_getName(ivar)
  • free(ivars)
  • method_exchangeImplementations(Method, Method)

(3) Application

  • Objc_setAssociatedObject Add attributes to classes
  • Method Swizzling adds and replaces and KVO implementations
  • Message forwarding (Hot update) Fixes bugs (JSPatch)
  • NSCoding automatic archiving and automatic file solution
  • Implement automatic transformation of dictionaries and models (MJExtension)

practice

  1. Isa pointer points to a problem
    BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
    BOOL res2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
    BOOL res3 = [(id)[Person class] isKindOfClass:[NSObject class]];
    BOOL res4 = [(id)[Person class] isMemberOfClass:[NSObject class]];
    BOOL res5 = [(id)[Person class] isKindOfClass:[Person class]];
    BOOL res6 = [(id)[Person class] isMemberOfClass:[Person class]];
    NSLog(@"\n%d\n%d\n%d\n%d\n%d\n%d",res1,res2,res3,res4,res5,res6);
Copy the code
  1. With Runtime, a class is created dynamically while the program is running.
  2. Using Runtime, you can dynamically create a class’s properties/methods while the program is running.
  3. Iterate over all member variables of a class;

Declaration: refer to the following blog, after their own modification processing, for the record of learning to use

Do you know the difference between isKindOfClass and isMemberOfClass? IOS Runtime objc_msgSend