2008-11-08 10 views
22

? Una de las características del tiempo de ejecución del Objective C moderno (64 bits OS X e iPhone OS) es la capacidad de sintetizar dinámicamente ivars sin declararlas explícitamente la clase:¿Cuál es el mecanismo subyacente para la síntesis de ivar en el tiempo de ejecución de Objective C moderno

@interface MyClass : NSObject { 
// NSString *name; unnecessary on modern runtimes 
} 

@property (retain) NSStrng *name; 

@end 

@implementation MyClass 

@synthesize name; 

@end 

en un poco de mi código que utilice implementaciones getter personalizados para inicializar las propiedades:

- (NSString *) name { 
    if (!name) { 
    name = @"Louis"; 
    } 

    return name; 
} 

lo anterior es incompatible con Ivars sintetizados ya que necesita tener acceso a una una ivar que no es declar ed en el encabezado. Por diversas razones, me gustaría actualizar varios de mis marcos personales para utilizar ivars sintetizados cuando se construyen en los tiempos de ejecución modernos, el código anterior debe modificarse para que funcione con ivars sintetizados con el fin de lograr ese objetivo.

Mientras que la documentación de Objective C 2.0 indica que los accesadores sintetizados en el tiempo de ejecución moderno sintetizarán el ivar en el primer uso. No especifica qué mecanismo de bajo nivel se usa para hacer esto. ¿Lo hace class_getInstanceVariable(), se han aflojado las restricciones en class_addIvar(), es una función no documentada en el tiempo de ejecución objetivo C 2.0? Si bien podría implementar mi propio almacenamiento lateral para los datos que respaldan mis propiedades, preferiría usar el mecanismo que utilizan los adaptadores sintetizados.

+1

estaría muy impresionado si tienes una respuesta a esta – Shawn

Respuesta

21

Fui y miré la documentación nuevamente, y creo que está malinterpretando. Los ivars sintetizados se crean en tiempo de compilación, no en tiempo de ejecución.

De acuerdo con la Objective-C 2.0 documentation:

Existen diferencias en el comportamiento que dependen del tiempo de ejecución (véase también “Diferencias de tiempo de ejecución”):

Para los tiempos de ejecución de legado, las variables de instancia que ya deben ser declarados en el bloque @interface. Si existe una variable de instancia del mismo nombre y tipo compatible que la propiedad, se usa; de lo contrario, se obtiene un error de compilación.

Para los tiempos de ejecución modernos, las variables de instancia se sintetizan según sea necesario. Si ya existe una variable de instancia del mismo nombre, se usa.

Así que todo lo que necesita hacer es declarar la variable de instancia que necesita, y el mismo código funcionará en ambos tiempos de ejecución ...

+2

Después de leer a través de código sintetizador de gcc esto en realidad lo que es pasando. –

+1

Una de las mejoras en los compiladores de la era Xcode 3.2 (Clang/LLVM y GCC 4.2) es que puede acceder a los ivars que se crean para respaldar variables sintetizadas incluso si no están declaradas en la clase, lo que hace que todo esto sea discutible . –

-6

añades propiedades en tiempo de ejecución con el NSKeyValueCoding Protocol.

[myObject setValue:@"whatever" forKey:@"foo"]; 
+2

Eso es incorrecto. Puede * establecer * valores con codificación de clave-valor, pero no puede agregar propiedades de esa manera. – jlehr

+0

Puede absolutamente agregar nuevos valores con NSKeyValueCoding si la clase implementa ese protocolo. Pero tiene razón, esta es la respuesta incorrecta a esta pregunta, ya que los ivars se crean en tiempo de compilación, no con NSKeyValueCoding. – jazzdev

+1

Vuelve a leer la respuesta. No puede agregar * propiedades * a través de la codificación de clave-valor. – jlehr

0

Lo que se busca es @synthesized nombre, como:

@synthesize name = _name; 

... 

- (NSString *) name { 
    if (!name) { 
     _name = @"Louis"; 
    } 

    return _name; 
} 
Cuestiones relacionadas