2009-10-16 12 views
6

tengo una clase que tiene este aspecto:#typedef y KVC en ObjC

@interface Properties : NSObject { 
@private 
    NSNumber* prop1; 
    NSNumberBool* prop2; 
    //etc 

donde NSNumberBool es un typedef:

// in MyApp_Prefix.pch 
typedef NSNumber NSNumberBool; 

tengo todas las declaraciones @property y @synthesize requeridos a hacer propiedades prop1 y prop2.

Todo compilado y funcionó bien hasta que intenté acceder a prop2 por [myProperties valueForKey: @ "prop2"]. Esto me da un error de "clase no cumple con el valor clave". Sin embargo, muchas llamadas similares funcionan bien:

myProperties.prop2; //works 
[myProperties prop2]; //works 
[myProperties valueForKey:@"prop1"]; //works 
[myProperties valueForKey:@"prop2"] // throws NSUnknownKeyException ?? 

¿Qué está pasando aquí, y cómo puedo solucionarlo?

Gracias,

+1

Realmente extraño, encontrándose con el mismo problema.Además, si lo hace '[myProperties respondsToSelector: @selector (prop2)]' también devuelve SÍ – jjramos

Respuesta

1

Esta es una publicación bastante antigua, pero llegué a ella mientras buscaba una solución a este problema, que está muy bien solucionada por la directiva Objective-C 2.0 @compatibility_alias. Esto le permite escribir:

@compatibility_alias NSNumber NSNumberBool; 

y tienen un alias creado para NSNumber. KVO funciona perfectamente con eso.

Sobre la respuesta actualmente aceptada, esto tiene la gran ventaja de ser seguro para el tipo.

4

De compilar el ejemplo y la emisión de class-dump en él, parece que el typedef se está convirtió en

struct NSNumber { 
    Class _field1; 
}; 

@interface Properties : NSObject 
{ 
    NSNumber *prop1; 
    struct NSNumber *prop2; 
} 

Cambiar el typedef a esto parece funcionar bien, aunque tal vez no es exactamente lo usted quiere.

#define NSNumberBool NSNumber 
+0

Gracias. Buena explicación + solución decente – tba

4

Sospecho que esto es un problema con la forma en que typedef interactúa con el método de codificación.

Creo que typedef sigue siendo una palabra clave C pura y realmente solo funciona con los "tipos" de Objective-C generalmente porque se implementan como estructuras.

Como resultado, al escribirde NSNumber a NSNumberBool, funciona bien para llamadas de método (y propiedades de sintaxis de punto) pero (suponiendo que mi teoría sea correcta) codifica rupturas que no pueden decir que NSNumberBool y NSNumber son del mismo tipo.

Me interesará ver lo que dice alguien que sabe mejor.

1

Similar a la respuesta de nall, también probé el volcado de clase. Encontré una solución interesante, aunque fea. El siguiente código:

typedef NSNumber* NSNumberBoolPtr; 

@interface Test : NSObject { 
    NSNumber *real; 
    NSNumberBoolPtr poser; 
} 

clase vuelca a:

@interface Test : NSObject 
{ 
    NSNumber *real; 
    NSNumber *poser; 
} 

@end 

Una vez más, no es exactamente lo que quiere, pero que le dan el tiempo de compilador de comprobación de no tener NSNumbers y NSNumberBools entremezclándose (que es Asumo la razón del typedef en primer lugar).