2010-01-27 12 views
13

Tengo un modelo de Datos centrales donde tengo una entidad A, que es un resumen. Entidades B, C, y D heredan de entidad A. Hay varias propiedades definidas en la entidad A que son utilizados por B, C, y D.Agregar métodos personalizados a un NSManagedObject subclasificado

me gustaría aprovechar esta herencia en mi código modelo. Además de las propiedades, me pregunto si puedo agregar métodos a la entidad A, que se implementan en sus subentidades.

Por ejemplo:

  1. I añadir un método para la interfaz para la entidad A que devuelve un valor y toma un argumento
  2. I añadir implementaciones de este método para A, B, C, D
  3. Entonces, me llaman executeFetchRequest: para recuperar todas las instancias de B
  4. que llamo el método de los objetos recuperados, que debe llamar a la aplicación del método que figura en la implementación del B

He intentado esto, pero al llamar al método, que recibirá:

[NSManagedObject methodName]: selector no reconocido enviado a la instancia

Supongo que esto se debe a que los objetos devueltos por executeFetchRequest: son objetos proxy de algún tipo.

¿Hay alguna forma de aprovechar la herencia utilizando NSManagedObjects subclase?

Me gustaría poder hacer esto, de lo contrario, mi código de modelo sería responsable de determinar qué tipo de NSManagedObject está tratando y realizar una lógica especial según el tipo, lo cual es indeseable.

Se agradece cualquier ayuda, gracias de antemano.

Respuesta

25

Debería funcionar. Los objetos devueltos por executeFetchRequest: son instancias reales de NSManagedObject s (o subclases de los mismos) Los pasos para usar clases personalizadas en CoreData son los siguientes. Digamos que tiene entidades A y B, donde B hereda de A. Luego hay dos clases personalizadas como

@interface A:NSManagedObject{ 
} 
-(void)someMethod:(NSString*)a; 
@end; 
@interface B:A{ 
} 
-(void)someMethod:(NSString*)a; 
@end; 

Entonces los puso en el modelador de datos XCode como se muestra:

screenshot of XCode modeler

De esta manera, el CoreData asigna automáticamente la clase correcta de la NSManagedObject cuando se obtiene de la base de datos.

+2

¡Muchas gracias! Mi modelo de datos estaba usando NSManagedObject; ¡Ni siquiera me había dado cuenta de que necesitaba especificar el nombre de la clase, funciona perfectamente! –

+9

No veo la captura de pantalla en esta respuesta. ¿Alguien podría reemplazarla (Yuji)? –

+0

Desafortunadamente, ¡la captura de pantalla no está disponible! :( –

18

Si obtiene esa excepción, significa que Core Data no está utilizando su clase personalizada. La clave aquí es NSManagedObject - ese es el objeto Core Data creado para los objetos en su almacén de datos.

Si aún no lo hizo, deberá crear una clase que herede de NSManagedObject, agregar allí sus métodos personalizados y luego establecer la entidad A para usar su clase personalizada en la herramienta de modelo de objetos. Si las entidades B, C, D, etc. tienen comportamientos específicos, debe subclasificar la clase que creó para la entidad A y asignar esas entidades para usar también las subclases.

Básicamente, tiene una jerarquía paralela: una jerarquía de entidades y otra de clases. Es probable que termine con la entidad X y la clase X para cada entidad en su modelo de objetos.

+1

Gracias, usted tenía la respuesta correcta, pero Yuji me proporcionó la captura de pantalla que realmente me apuntó en la dirección correcta. Si pudiera aceptar tu respuesta también, lo haría. –

+0

¡¡¡Es tan fácil olvidarse del modelo xcdata cuando cambia el nombre de una clase de entidad !! ¡Tu respuesta me ahorró mucho tiempo! Muchas gracias :-) – jpswain

+0

+1 Muchas gracias por la sugerencia "establecer entidad para utilizar su clase personalizada en la herramienta de modelo de objetos". ¡Para mí, no usé la clase generada automáticamente, así que me salté este paso! –

1

Tuve el mismo error por el mismo motivo subyacente, pero se produjo en una situación diferente y con una cura diferente. ¡Tu sugerencia me ayudó mucho!

Originalmente había creado mi clase implementando mi entrada a mano. No sabía que había un menú de Xcode para esto. ¡Creo que el enlace nunca estuvo allí! Así que no fue hasta que agregué y empecé a probar los nuevos métodos personalizados (no setter/getters) que comencé a obtener el error.

Mi solución fue cambiar el nombre de mi clase, hacer que Xcode vuelva a crear la clase para mi entrada a través de Editor->Create NS Mangage Object.... Luego cortar y pegar en el código anterior en la nueva clase. ¡Sin diferencia en el código!

Xcode parece tener algún tipo de enlace interno que no se ve en el código.

2

Después de intentar muchas llamadas a la solución isMemberOfClass en mi subclase NSManagedObject antes de tratar de usar mi método personalizado hizo el truco.

[thing isMemberOfClass:[Thing class]]; 
[thing customMethod]; //was getting unrecognized selector sent to instance here before 
+0

Esta fue la única solución que funcionó para mí. Creo que esto tiene que ver con el hecho de que mi código CoreData está dentro de una biblioteca estática en lugar de directamente en la aplicación principal, pero no estoy completamente seguro de eso. – BenV

+0

esto sí que me engañó, ya que mi código de datos centrales está en la biblioteca estática y lo uso como subproyecto en otra aplicación +1 para su respuesta @ micheal23 – Talha

Cuestiones relacionadas