2010-06-19 10 views
102

¿Las propiedades en Objective-C 2.0 requieren que se declare una variable de instancia correspondiente? Por ejemplo, yo estoy acostumbrado a hacer algo como esto:¿Las propiedades declaradas requieren una variable de instancia correspondiente?

MyObject.h

@interface MyObject : NSObject { 
NSString *name; 
} 
@property (nonatomic, retain) NSString *name; 
@end 

MyObject.m

@implementation 
@synthesize name; 
@end 

Sin embargo, lo que si lo hiciera en su lugar:

MyObject.h

@interface MyObject : NSObject { 
} 
@property (nonatomic, retain) NSString *name; 
@end 

¿Esto sigue siendo válido? ¿Y es de alguna manera diferente a mi ejemplo anterior?

+0

¿Por qué es el segundo 'MyObject.h' en negrita no 'MyObject.m'? –

Respuesta

94

Si está utilizando el Modern Objective-C Runtime (que es iOS 3.xo superior, o Snow Leopard de 64 bits o superior), entonces necesita , no necesita definir ivars para sus propiedades en casos como este .

Cuando usted @synthesize la propiedad, el ivar será en efecto sintetizado también para usted. Esto evita el escenario "frágil-ivar". Puede leer más al respecto en Cocoa with Love

69

En su interfaz, puede declarar formalmente una variable de instancia entre llaves, o mediante @property fuera de las llaves, o ambas. De cualquier manera, se convierten en atributos de la clase. La diferencia es que si declara @property, puede implementar usando @synthesize, que autocodifica su getter/setter por usted. El colocador de autocodificador inicializa enteros y flotantes a cero, por ejemplo. SI declara una variable de instancia, y NO especifica un @property correspondiente, entonces no puede usar @synthesize y debe escribir su propio getter/setter.

Siempre puede anular el eliminador/ajustador autocodificado especificando el suyo. Esto se hace comúnmente con la propiedad managedObjectContext, que está cargada con holgura. Por lo tanto, declara su managedObjectContext como una propiedad, pero también escribe un método -(NSManagedObjectContext *)managedObjectContext. Recuerde que un método, que tiene el mismo nombre que una variable/propiedad de instancia, es el método "getter".

El método de declaración @property también le permite otras opciones, como retain y readonly, que no es el método de declaración de variable de instancia. Básicamente, ivar es la forma antigua, y @property lo extiende y lo hace más elegante/más fácil. Puede referirse a usar el yo. prefijo, o no, no importa, siempre y cuando el nombre sea exclusivo de esa clase. De lo contrario, si su superclase tiene el mismo nombre de una propiedad que usted, entonces tiene que decir ya sea como self.name o super.name para especificar de qué nombre está hablando.

Por lo tanto, se verá cada vez menos personas declaran ivar s entre las llaves, y en lugar de cambiar hacia especificando sólo @property, y luego hacer @synthesize. No puede hacer @synthesize en su implementación sin un correspondiente @property. El sintetizador solo sabe qué tipo de atributo es de la especificación @property.La declaración de sintetizar también le permite cambiar el nombre de las propiedades, de modo que puede referirse a una propiedad por un nombre (taquigrafía) dentro de su código, pero afuera en el archivo .h use el nombre completo. Sin embargo, con la autocompleta realmente genial que XCode tiene ahora, esta es una ventaja menor, pero aún está ahí.

Espero que esto ayude a aclarar toda la confusión y desinformación que está flotando por ahí.

+3

Excelente explicación ... –

+0

realmente excelente – Fab1n

+1

¡Esta respuesta me borró semanas de confusión! –

3

De la documentación:

En general el comportamiento de las propiedades es idéntica en ambos tiempos de ejecución modernos y heredados (ver “Versiones en tiempo de ejecución y plataformas” en la Guía de Objective-C de tiempo de ejecución de programación). Hay una diferencia clave: el tiempo de ejecución moderno admite la síntesis de variable de instancia mientras que el tiempo de ejecución heredado no.

Para que @synthesize funcione en el tiempo de ejecución heredado, debe proporcionar una variable de instancia con el mismo nombre y tipo compatible de la propiedad o especificar otra variable de instancia existente en la instrucción @synthesize. Con el tiempo de ejecución moderno, si no proporciona una variable de instancia, el compilador agrega uno para usted.

8

funciona en ambos sentidos pero si no los declaras en las llaves, no verás sus valores en el depurador en xcode.

1

The Objective-C Programming Language: Property Implementation Directives

Hay diferencias en el comportamiento de la síntesis de acceso que dependen del tiempo de ejecución (véase también “Diferencia de tiempo de ejecución”):

  • Para los tiempos de ejecución de legado, las variables de instancia que ya debe ser declarado en el bloque @interface de la clase actual. Si existe una variable de instancia del mismo nombre que la propiedad, y si su tipo es compatible con el tipo de propiedad, se utiliza; de lo contrario, se obtiene un error de compilación.

  • Para los tiempos de ejecución modernos (consulte "Versiones de tiempo de ejecución y plataformas" en la Guía de programación de tiempo de ejecución de Objective-C), las variables de instancia se sintetizan según sea necesario. Si ya existe una variable de instancia del mismo nombre, se usa.

3

Si está utilizando XCode 4.4 o temprano se va a generar código de ejemplo de síntesis variable para ti.

Solo tiene que declarar propiedades como a continuación; generará código de sintetización y código de declaración de variable de instancia para usted.

@property (nonatomic, strong) NSString *name; 

que va a generar la síntesis de código como

@synthesize name = _name; 

y se puede acceder a la variable de instancia usando _name es similar a declarar

NSString* _name 

pero si se declara propiedad de sólo lectura se como

@property (nonatomic, strong, readonly) NSString *name; 

que generará código

@synthesize name; 

o

@synthesize name = name; 

por lo que debe tener acceso a nombre de la variable instantánea con el prefijo a cabo "_" cualquier manera que usted puede escribir su propio código de síntesis a continuación, compilador generará código para tú. puede escribir

@synthesize name = _name; 
Cuestiones relacionadas