usar una superclases subclase significa que programacion metodo llamar heredado ejemplos como clases clase objective-c initialization

objective c - superclases - Crea una subclase de una clase usando init de padres-de otra clase



que significa super() java (2)

Como parte de su mapeo, debe saber qué subclase necesita. Entonces usa

ManagedEntity *newEntity = [[NSClassFromString(className) alloc] initWithEntityDescription:_entityDescription];

EDITAR: Estaba construyendo esto en un proyecto de GitHub como prometí y me di cuenta de por qué no compila. Debe tener -initWithEntityDescription: declarado en una clase conocida a la que se puede acceder dentro del alcance. En este caso, significa que debe declarar e implementar ManagedEntity -initWithEntityDescription: y debe tener `#import" ManagedEntity.h "en la parte superior de su archivo.

Editar: Este síndromo de downvoting aquí apesta a lo grande. Hice una pregunta en la que, en mi opinión, demostré que hice mi tarea y le pedí consejo. Las respuestas subidas de tono implicaban ir con advertencias de tiempo de compilación, mientras que mi propia y probablemente la forma más limpia de OOP no recibió ningún interés.

Breve reseña para entender por qué necesito esto y lo que trato de hacer: estoy escribiendo un ORM que implementa el patrón del mapeador de datos. Un asignador (es decir, para los resultados de SQLite) debe crear subclases de una clase de entidad, utilizando el inicializador de la clase de entidad base. Entonces está el problema.

El asignador no sabe, y no debería, conocer clases específicas. Las descripciones de mapeo y mapeadores específicos para diferentes orígenes de datos se abstraen de la clase de entidad y, por diseño, forman parte de la descripción de la entidad.

Las entidades son similares a NSManagedObject, aunque el ORM sigue un patrón diferente. La descripción con la que se crea cualquier entidad es similar a NSEntityDescription (pero también sigue un patrón y propósito diferentes).

Entonces mi objetivo es crear entidades que sé que son subclases de ManagedEntity, usando el método init de ManagedEntity.

Entonces el init de mi mapper se ve así:

- (id)initWithEntityClass:(Class)EntityClass entityDescriptor:(EntityDescription*)entityDescriptor { self = [super init]; if (self) { _EntityClass = EntityClass; _entityDescription = entityDescription; ... (assert that class is of subclass of ManagedEntity) }

Y algún tiempo después, en mi mapeador, quiero crear la entidad concreta:

-(void)createEntityWithSQLiteResultSet:(sqlite3_stmt*)resultSet { // Problem: How to init a class known to be a subclass of ManagedEntity? ManagedEntity *newEntity = [[_EntityClass] alloc] initWithEntityDescription:_entityDescription]; }

Entonces, ¿cómo creo esta clase secundaria de ManagedEntity, usando init de ManagedEntity?

Claro, podría usar respondsToSelector () para initWithEntityDescription e invocar eso. Pero algo me dice que debería haber una manera más elegante donde el tipo de clase ya se conoce. Además, respondsToSelector y la invocación del selector solo harán una verificación de tiempo de ejecución. Aunque el inicializador de entidad no debe cambiar, parece una mala elección perder el tiempo de compilación comprobando si este método existe.


Para reforzar la respuesta correcta de Neal, las afirmaciones de OP no pueden funcionar porque él sabe objC :)

#import <CoreData/CoreData.h> @interface TestMapper : NSObject - (NSManagedObject*)createClassForEntity:(NSEntityDescription*)entity context:(NSManagedObjectContext*)ctx; @end

#import "TestMapper.h" @implementation TestMapper - (NSDictionary*)entityToClassMap { return nil; //TODO ;) } - (NSManagedObject*)createClassForEntity:(NSEntityDescription*)entity context:(NSManagedObjectContext*)ctx { NSString *className = self.entityToClassMap[entity.name]; assert(className); return [[NSClassFromString(className) alloc] initWithEntity:entity insertIntoManagedObjectContext:ctx]; } @end

alternativa utilizando el tiempo de ejecución que desea

id cls = NSClassFromString(className); id alloced_cls = objc_msgSend(cls, @selector(alloc)); id newEntity = objc_msgSend(alloced_cls, @selector(initWithEntity:insertIntoManagedObjectContext:), entity, ctx); return newEntity;