Pregunta

Estoy trabajando en una fábrica de objetos para hacer un seguimiento de una pequeña colección de objetos. Los objetos pueden ser de diferentes tipos, pero todos responderán a createInstance y reset . Los objetos no pueden derivarse de una clase base común porque algunos de ellos deberán derivarse de clases de cacao incorporadas como NSView y NSWindowController .

Me gustaría poder crear instancias de cualquier objeto adecuado simplemente pasando el nombre de clase deseado a mi fábrica de la siguiente manera:

myClass * variable = [factory makeObjectOfClass:myClass];

El método makeObjectOfClass: se vería así:

- (id)makeObjectOfClass:(CLASSNAME)className
{
    assert([className instancesRespondToSelector:@selector(reset)]);
    id newInstance = [className createInstance];
    [managedObjects addObject:newInstance];
    return newInstance;
}

¿Hay alguna manera de pasar un nombre de clase a un método, como lo hice con el argumento (CLASSNAME) className a makeObjectOfClass: anterior?

En aras de la exhaustividad, esta es la razón por la que quiero administrar todos los objetos. Quiero poder restablecer el conjunto completo de objetos de una sola vez, llamando a [restablecimiento de fábrica]; .

- (void)reset
{
    [managedObjects makeObjectsPerformSelector:@selector(reset)];
}
¿Fue útil?

Solución

Puede convertir una cadena en una clase utilizando la función: NSClassFromString

Class classFromString = NSClassFromString(@"MyClass");

Sin embargo, en su caso, sería mejor utilizar los objetos de clase directamente.

MyClass * variable = [factory makeObjectOfClass:[MyClass class]];

- (id)makeObjectOfClass:(Class)aClass
{
    assert([aClass instancesRespondToSelector:@selector(reset)]);
    id newInstance = [aClass createInstance];
    [managedObjects addObject:newInstance];
    return newInstance;
}

Otros consejos

Tengo un mejor tutorial sobre eso, por favor revisa https://appengineer.in/ 2014/03/13 / send-class-name-as-a-argumento-en-ios /

Es bastante fácil especificar dinámicamente una clase, de hecho, puede hacer referencia a ella por su nombre:

id string = [[NSClassFromString(@"NSString") alloc] initWithString:@"Hello!"];
NSLog( @"%@", string );

Otro consejo, evitaría usar la nomenclatura 'objeto administrado' ya que la mayoría de los otros programadores de Cocoa lo leerán como NSManagedObject, de Core Data. También puede resultarle más fácil usar una NSNotification global (a la que se suscriben todos sus objetos reiniciables) en lugar de administrar una colección de diferentes tipos de objetos, pero está más informado para tomar esa decisión que yo.

La parte de la respuesta que falta en las otras respuestas es que puede definir un @protocol que contenga sus métodos + createInstance y + reset .

Parece que quieres algo como:

- (id)makeObjectOfClassNamed:(NSString *)className
{
    Class klass = NSClassFromString(className);
    assert([klass instancesRespondToSelector:@selector(reset)]);
    id newInstance = [klass createInstance];
    [managedObjects addObject:newInstance];
    return newInstance;
}

Esto supondría un método de clase llamado + createInstance . O simplemente puede usar [[klass alloc] init] .

Para llamarlo:

MyClass *variable = [factory makeObjectOfClassNamed:@"MyClass"];

Dependiendo de lo que intente hacer, podría ser mejor pasar objetos de clase que cadenas, por ejemplo:

MyClass *variable = [factory makeObjectOfClass:[MyClass class]];
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top