Objective-C class -> cadena como: [NSArray className] -> @ “NSArray”

128

Estoy tratando de obtener un nombre de cadena de una clase del propio objeto de clase.

// For instance
[NSArray className]; // @"NSArray"

He encontrado, object_getClassName(id obj)pero eso requiere que se le pase una instancia, y en mi caso es un trabajo innecesario.

Entonces, ¿cómo puedo obtener una cadena de un objeto de clase, y no una instancia?

Alex Wayne
fuente

Respuestas:

305
NSString *name = NSStringFromClass ([NSArray class]);

Incluso puedes volver al otro lado:

Class arrayClass = NSClassFromString (name);
id anInstance = [[arrayClass alloc] init];
dreamlax
fuente
¡Gracias! ¿Cómo se NSStringFromClassimplementa? ¿Es más eficiente almacenar el nombre de la clase en una static NSStringvariable?
ma11hew28
13
@MattDiPasquale: todos los nombres de clase se almacenan en algún lugar del tiempo de ejecución de Objective-C (los elementos internos del tiempo de ejecución se ocultan principalmente de la aplicación y se exponen solo a través de algunas funciones API). Cada objeto de clase (por ejemplo [NSArray class]) es en realidad un struct. El structcontiene una gran cantidad de información acerca de la clase, incluyendo su nombre, los métodos que implementa, la superclase, etc. NSStringFromClasssimplemente tira del nombre de la clase de esta structy la convierte en una NSString. No almacene el nombre de la clase en un static NSString, no ofrecerá ninguna ventaja de rendimiento.
dreamlax
3
@MattDiPasquale: NSClassFromStringfunciona un poco diferente. Dado que todos los nombres de clase existen en algún lugar del tiempo de ejecución de Objective-C, NSClassFromStringtoma la cadena y explora la lista de clases mantenida por el tiempo de ejecución buscando la clase que tiene el nombre dado. Si lo encuentra, lo devuelve, de lo contrario, vuelve Nil.
dreamlax
2
@MattDiPasquale: "¿Cómo se implementa NSStringFromClass?" si realmente quiere saber, es probable que utiliza class_getName()en el tiempo de ejecución, que devuelve una cadena C
user102008
2
@AlexZavatone: classNamees un método agregado por las extensiones de secuencias de comandos que solo está disponible en Mac OS X, incluso entonces es complicado en cómo funciona porque no está completamente documentado (o al menos no fue la última vez que lo verifiqué). NSStringFromClass()es la forma correcta de hacerlo.
dreamlax
1

Aquí hay una forma diferente de hacerlo con un poco menos de tipeo:

NSString *name = [NSArray description];
Sherwin Zadeh
fuente
77
Eso no garantiza hacer lo que se solicita. Ese método generalmente se anula para proporcionar una descripción del objeto y los datos que contiene.
Alex Wayne
3
Sé que se anula como método de INSTANCE, pero ¿con qué frecuencia se anula el MÉTODO DE CLASE + descripción? En cualquier caso, vale la pena considerarlo si no fuera por cada clase ... No creo que se requiera una rebaja.
Sherwin Zadeh
1
@SherwinZadeh: Creo que en la práctica, es poco probable que encuentre clases que se hayan anulado +description, sin embargo, en teoría, este no es el propósito +description, por lo que este método es frágil para determinar los nombres de clase.
dreamlax
1

Considere esta alternativa:

const char *name = class_getName(cls);

Es mucho más rápido, ya que no tiene que asignar objetos NSString y convertir ASCII a cualquier NSStringrepresentación. Así es como NSStringFromClass()se implementa.

wonder.mice
fuente
Esto fue útil para mí, pero necesitaba agregar #import <objc / runtime.h> en la parte superior del archivo.
Sparklellama