La relación entre clases de iOS y metaclases

Todo es así, los estudiantes quieren verificar si resolveClassMethod se ejecuta (resolveClassMethod es cuando un objeto llama a un método de clase inexistente, este método se ejecutará, si no lo entiende, debe compensarlo, puede leer este artículo: Objetivo- Reenvío de mensajes C ) y luego envió el siguiente código:

[NSObject performSelector:@selector(hehe)];

Después de leerlo, estaba confundido. PerformSelector es un método de instancia y NSObject es una clase. ¿No compila un error? Posteriormente, la prueba encontró que no habría ningún error.

Entonces comenzó nuestra historia de hoy:
todos sabemos que escribir así comete errores

@interface TestObject : NSObject
@end
@implementation TestObject
- (void)method1{
       [TestObject method2];//这样调用一定会编译错误
}
- (void)method2{}

Sin embargo, escribir de esta manera no reportará un error.

@interface TestObject : NSObject
@end
@implementation TestObject
- (void)method{
   [NSObject performSelector:@selector(hehe)];
}

Incluso escribir así no informará de
un error. Cree una categoría de NSObject

@interface NSObject (hehe)
+(void)run;
@end
@implementation NSObject (hehe)
-(void)run{
    NSLog(@"run.....");
}
@end

Luego llame

[NSObject run];

¿Por qué es esto?

Mira un diagrama

Imagen.png

 

(Esta imagen proviene de la red)
Suponiendo que la clase A hereda de la clase B, la clase B hereda de NSObject
A es la Subclase (clase) en camino, B es la Superclase (clase) en la figura y NSObject es la clase Raíz (clase);
A * a = [A new];
De hecho, A es lo mismo que a, pero también un objeto, A se llama objeto de clase y a se llama objeto de instancia.
Cada objeto de clase tiene un puntero isa

 Class isa  OBJC_ISA_AVAILABILITY;

El puntero isa apunta a la metaclase del objeto de esa clase. Cada clase es un objeto de su metaclase. La metaclase es la descripción del objeto de clase, al igual que la descripción del objeto de instancia ordinario.

La esencia del método de clase declarado en cada clase es poner el método en la lista de métodos de la metaclase, por lo que cuando la clase llama al método de clase, se puede imaginar que el objeto de la metaclase está llamando a un método de instancia.

La clase padre de A es B, la clase padre de la metaclase de A es la clase padre de la metaclase B, el padre de B es NSObject, el padre de NSObject es nulo y el padre de la metaclase B es la metaclase de NSObject; preste especial atención Un punto, la clase principal de la metaclase de NSObject es NSObject, y el puntero isa de NSObject apunta a la metaclase de NSObject. Por lo tanto, todos los métodos en NSObject también pertenecen a la metaclase de NSObject. 1, así que use NSObject para llamar a cualquier NSObject en Los métodos de instancia son todos exitosos, 2. Esto también explica que la declaración anterior es + (void) run; método de clase, y la implementación es - (void) run {NSLog (@ "run .....") ;} Método de instancia, la llamada no se bloqueará.

La clase y la metaclase son un ciclo cerrado. La instancia apunta a la clase, la clase apunta a la metaclase, la metaclase apunta a la metaclase y la metaclase apunta a sí misma. La clase principal de la metaclase raíz es NSObject.

Las metaclases son clases de objetos de clase. Cada clase (Clase) tiene su propia metaclase única (cada clase tiene su propia lista única de métodos). Esto significa que todos los objetos de clase son diferentes.

Todos los métodos de poder en NSObject, cualquier clase se pueden llamar a través de métodos de clase.

Todas las metaclases usan la metaclase de la clase base como su clase base. Lo mismo es cierto para la metaclase de la clase base de nivel superior, excepto que apunta a sí misma.

Supongo que te gusta

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