¿Crear una instancia de clase objective-c por nombre?


¿Es posible crear una instancia de una clase por nombre? Algo como:

NSString* className = @"Car";
id* p = [Magic createClassByName:className];
[p turnOnEngine];

No se si esto es posible en objective-c pero parece que lo sería,

Author: Dori, 2009-07-23

4 answers

id object = [[NSClassFromString(@"NameofClass") alloc] init];
 213
Author: Chris McCall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-23 19:59:20

NSClassFromString() corre el riesgo de escribir mal el nombre de la clase o de usar una clase que no existe. No lo descubrirá hasta el tiempo de ejecución si comete ese error. En su lugar, si usa el tipo objective-c incorporado de Class para crear una variable, entonces el compilador verificará que la clase existe.

Por ejemplo, en su .h:

@property Class NameOfClass;

Y luego en su .m:

id object = [[NameOfClass alloc] init];

Si escribiste mal el nombre de la clase o si no existe, obtendrás un error en tiempo de compilación. También creo que este es un código más limpio.

 38
Author: Simon Woodside,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-16 01:27:27

Si está trabajando con Objective-C sin el NeXTstep (OS X, iOS, GNUstep etc) o simplemente piensa que este método es más limpio, entonces podría utilizar la API de la biblioteca de tiempo de ejecución del lenguaje Objective-C. En Objective-C 2.0:

#import <objc/runtime.h>
//Declaration in the above named file
id objc_getClass(const char* name);
//Usage
id c = objc_getClass("Object");
[ [ c alloc ] free ];

Bajo Objective-C (1.0 o versión sin nombre) utilizarías lo siguiente:

#import <objc/objc-api.h>
//Declaration within the above named file
Class objc_get_class( const char* name);
//Usage
Class cls = objc_get_class( "Test" );
id obj = class_create_instance( cls );
[ obj free ];

No he probado la versión 1.0, sin embargo, he utilizado la función 2.0 en el código que ahora está en producción. Yo personalmente creo que la utilización la función 2.0 es más limpia si está disponible que la función NS, ya que consume menos espacio: the length of the name in bytes + 1 ( null terminator ) para la API 2.0 versus the sum of two pointers (isa, cstring), a size_t length (cstring_length) y length of the string in bytes + 1 para la API NeXTSTEP.

 8
Author: Mark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-07 10:16:34
@interface Magic : NSObject
+ (id)createInstanceOfClass:(Class)classe;
@end

@implementation Magic

+ (id)createInstanceOfClass:(Class)classe
{
    return [[classe alloc] init];
}

@end

Entonces para usarlo:

Car *car = [Magic createInstanceOfClass:[Car class]];
[car engineTurnOn];
 2
Author: Skela,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-10 04:16:10