2011-09-13 11 views
6

Tengo una NSManagedObject subclase MyClass con una propiedad myProp, que se define @dynamic. Hay varias instancias de lectura myProp en mi código, a través de [myClass myProp].Objective-C: override dynamic getter

Ahora, quiero definir un getter (que devuelve myProp después de agregarle algo) para myProp, sin cambiar las varias llamadas a [myClass myProp]. es decir, sin crear un captador que tenga otro nombre que no sea getMyProp.

Mi pregunta es, si creo un getter getMyProp, que reemplazará el getter creado por NSManagedObject, ¿cómo accedo al valor original que está almacenado en la base de datos?

Gracias,

Akshay

Respuesta

17

Para acceder a los valores subyacentes de un objeto administrado utiliza los dos métodos siguientes:

- (id)primitiveValueForKey:(NSString *)key

- (void)setPrimitiveValue:(id)value forKey:(NSString *)key

Esto se utiliza a menudo para convierte atributos NSNumber en su tipo 'real', por ejemplo, una propiedad bool:

- (BOOL)isShared 
{ 
    [self willAccessValueForKey:@"isShared"]; 
    NSNumber *underlyingValue = [self primitiveValueForKey:@"isShared"]; 
    [self didAccessValueForKey:@"isShared"]; 
    return [underlyingValue boolValue]; 
} 

El willAccessValueForKey: y didAccessValueForKey: son requeridos por la clase de objeto gestionado subyacente para el tratamiento de fallos y relaciones etc.

Y si lo hace llegar a escribir un organismo, también se debe envolver el descriptor de acceso en los métodos de KVC:

- (void)setShared:(BOOL)isShared 
{ 
    NSNumber *newUnderlyingValue = [NSNumber numberWithBool:isShared]; 
    [self willChangeValueForKey:@"isShared"]; 
    [self setPrimitiveValue:newUnderlyingValue forKey:@"isShared"]; 
    [self didChangeValueForKey:@"isShared"]; 
} 

Habiendo dicho esto, yo personalmente no recomendaría que se mantenga el mismo nombre de método a menos que tenga un buen motivo. Para los valores 'derivados' generalmente desea crear un nuevo método con un nombre diferente. No toma mucho tiempo hacer un rápido descubrimiento/reemplazo a través de su código.

EDIT: añadido willAccessValueForKey:/didAccessValueForKey: (jrturton gracias)

+0

¿Usted también tiene que poner entre paréntesis el código de captador con 'willAccessValueForKey:' y 'didAccessValueForKey:' para asegurar que los fallos se disparan si es necesario? – jrturton

+0

Sí, gracias, me perdí eso, actualicé el código. –

+0

Muchas gracias Mike! – Akshay