Tiempo de ejecución 与 Aspectos

Es un puntero de Runtime

111.png

1. Vista horizontal: una instancia es un objeto, una clase también es un objeto (objeto de clase) y una metaclase también es un objeto (objeto de clase original).
Este es un punto muy importante. Espero que todos entiendan que ignoraremos la estructura superior e inferior aquí. Primero, mire la estructura izquierda y derecha. El punto a la derecha es el punto de isa en la estructura objc_class en el código fuente en tiempo de ejecución presentado anteriormente. Instancia se refiere al objeto que creamos y Subclass (clase) es la clase que creó el objeto. Nota: La clase que creó el objeto en sí también es un objeto, llamado Es un objeto de clase La información almacenada en el objeto de clase está relacionada con la descripción de la instancia, como las variables miembro y el método de instancia de la instancia.
El puntero isa en el objeto de clase apunta a Subclase (meta). Subclase (meta) también es un objeto. Es el objeto de clase original. El objeto de clase original almacena información relacionada con la clase de descripción, como los métodos de clase. En este proceso, el isa Las dos direcciones son muy similares, así que preste atención a la comprensión.
2. Vista longitudinal: el
puntero de superclase es fácil de entender, apunta hacia arriba de acuerdo con la relación de herencia y alcanza la parte superior de la cadena de herencia.

Referencia: ¿Por qué el puntero devuelto por object_getClass (obj) es diferente de [clase OBJ]?

Clase de método de instancia y clase de método de clase

  • El método de clase está en la metaclase, el método de clase es regresar a sí mismo y el método de instancia es la clase que devuelve la instancia isa
+ (Class)class {
    return self;
}

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

Algunos métodos de Runtime

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

Mecanismo de reenvío de mensajes

Mecanismo de reenvío de mensajes

Aspectos

  • Procesos de aspectos
    1) agregar una relación de asociación al objeto : aspectos__viewDidLoad contenido relacionado es aspectContainer
    2) generar un identificador del objeto y sel
    3) agregar el identificador al contenedor
    4.1) generar clase _Aspects_AspectsViewController, _Aspects_AspectsViewController es una subclase de AspectViewController.
    4.2) Modificar la implementación de la función forwardInvocation de _Aspects_AspectsViewController a _ ASPECTS_ARE_BEING_CALLED_ .
    4.3) _Aspects_AspectsViewController agrega el método __aspects_forwardInvocation, la realización de __aspects_forwardInvocation es la realización de la función forwardInvocation original.
    4.4) Modifique la clase original del objeto, el puntero isa se cambia de AspectViewController a _Aspects_AspectsViewController.
    5) Agregue el método aspectos__viewDidLoad a la clase _Aspects_AspectsViewController que es la implementación del viewDidLoad original
    6) Modifique el método viewDidLoad en la clase _Aspects_AspectsViewController a _objc_msgForward

  • Tomemos el ejemplo de insertar un fragmento de código después del método viewWillAppear: de ViewControler para explicar los cambios antes y después del gancho. Antes del gancho, la relación entre SEL e IMP del ViewController es la siguiente

     

    222.png

333.png

Luego, echemos un vistazo a la secuencia de llamada real de viewWillAppear: después del gancho:

  • El objeto recibe el mensaje del selector (viewWillAppear :)
  • Busque el IMP correspondiente: _objc_msgForward y active el mecanismo de reenvío de mensajes después de la ejecución.
  • Objeto recibido hacia adelante Invocación: mensaje
  • Encuentre el IMP correspondiente: ASPECTS_ARE_BEING_CALLED , ejecute IMP
  • Envíe aspectos_viewWillAppear: al objeto para ejecutar el IMP del método viewWillAppear inicial
  • Ejecuta el código de bloque insertado
  • Si ViewController no puede responder a los aspectos_viewWillAppear, envía __aspects_forwardInvocation: al objeto para ejecutar el IMP forwardInvocation inicial
  • Por lo tanto, Aspects usa un método de gancho centralizado, y todas las llamadas se realizan finalmente con una función C ASPECTS_ARE_BEING_CALLED .

Mecanismo de reenvío de mensajes de referencia
y análisis del código fuente de Aspectos

 

Supongo que te gusta

Origin blog.csdn.net/wangletiancsdn/article/details/103313950
Recomendado
Clasificación