Runtime 与 Aspects

Runtime's isa pointer

111.png

1. Horizontal view: an instance is an object, a class is also an object (class object), and a meta class is also an object (original class object).
This is a very important point. I hope everyone understands that we ignore the upper and lower structure here. First look at the left and right structure, from the left The point to the right is the point of isa in the objc_class structure in the runtime source code introduced earlier. Instance refers to the object we created, and Subclass (class) is the class that created the object. Note: The class that created the object itself is also an object, called It is a class object. The information stored in the class object is related to the description of the instance, such as the member variables and the instance method of the instance.
The isa pointer in the class object points to Subclass (meta). Subclass (meta) is also an object. It is the original class object. The original class object stores information related to the description class, such as class methods. In this process, the isa The two directions are very similar, so pay attention to understanding.
2. Longitudinal view: The
superclass pointer is easy to understand. It points upward according to the inheritance relationship and reaches the top of the inheritance chain.

Reference: Why is the pointer returned by object_getClass(obj) different from [OBJ class]

Instance method class and class method class

  • The class method is in the meta class, the class method is to return itself, and the instance method is the class that returns the instance isa
+ (Class)class {
    return self;
}

- (Class)class {
    return object_getClass(self);
}

Some methods of Runtime

Method targetMethod = class_getInstanceMethod(klass, selector);//函数的实例
IMP targetMethodIMP = method_getImplementation(targetMethod);//函数的实现

Message forwarding mechanism

Message forwarding mechanism

Aspects

  • Aspects process
    1) add an association relationship to the object : aspects__viewDidLoad related content is aspectContainer
    2) generate an identifier from the object and sel
    3) add the identifier to the container
    4.1) generate class _Aspects_AspectsViewController, _Aspects_AspectsViewController is a subclass of AspectViewController.
    4.2) Modify the implementation of the forwardInvocation function of _Aspects_AspectsViewController to _ ASPECTS_ARE_BEING_CALLED_ .
    4.3) _Aspects_AspectsViewController adds the method __aspects_forwardInvocation, the realization of __aspects_forwardInvocation is the realization of the original forwardInvocation function.
    4.4) Modify the original class of the object, the isa pointer is changed from AspectViewController to _Aspects_AspectsViewController.
    5) Add the method aspects__viewDidLoad to the class _Aspects_AspectsViewController which is the implementation of the original viewDidLoad
    6) Modify the method viewDidLoad in the class _Aspects_AspectsViewController to _objc_msgForward

  • Let’s take the example of inserting a piece of code after the viewWillAppear: method of ViewControler to explain the changes before and after the hook. Before the hook, the relationship between the SEL and IMP of the ViewController is as follows

     

    222.png

333.png

Then, let's take a look at the actual call sequence of viewWillAppear: after the hook:

  • The object receives the message of selector(viewWillAppear:)
  • Find the corresponding IMP: _objc_msgForward, and trigger the message forwarding mechanism after execution.
  • Object received forwardInvocation: message
  • Find the corresponding IMP: ASPECTS_ARE_BEING_CALLED , execute IMP
  • Send aspects_viewWillAppear: to the object to execute the IMP of the initial viewWillAppear method
  • Execute the inserted block code
  • If the ViewController cannot respond to aspects_viewWillAppear, it sends __aspects_forwardInvocation: to the object to execute the initial forwardInvocation IMP
  • Therefore, Aspects uses a centralized hook method, and all calls are finally made with a C function ASPECTS_ARE_BEING_CALLED .

Reference
message forwarding mechanism and Aspects source code analysis

 

Guess you like

Origin blog.csdn.net/wangletiancsdn/article/details/103313950