objective-c - tipos - que es una clase en programacion
¿Las propiedades declaradas requieren una variable de instancia correspondiente? (6)
¿Las propiedades en Objective-C 2.0 requieren que se declare una variable de instancia correspondiente? Por ejemplo, estoy acostumbrado a hacer algo como esto:
MyObject.h
@interface MyObject : NSObject {
NSString *name;
}
@property (nonatomic, retain) NSString *name;
@end
MyObject.m
@implementation
@synthesize name;
@end
Sin embargo, ¿y si hiciera esto 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?
De la documentación:
En general, el comportamiento de las propiedades es idéntico en los tiempos de ejecución modernos y heredados (consulte "Versiones y plataformas en tiempo de ejecución" en la Guía de programación en tiempo de ejecución de Objective-C). 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.
En su interfaz, puede declarar formalmente una variable de instancia entre las 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 declaras @property
, puedes implementar usando @synthesize
, que @synthesize
tu getter / setter por ti. El colocador de autocodificador inicializa enteros y flotantes a cero, por ejemplo. SI declara una variable de instancia y NO especifica una @property
correspondiente, no puede usar @synthesize
y debe escribir su propio getter / setter.
Siempre puede anular el getter / setter autocodificado especificando el suyo. Esto se hace comúnmente con la propiedad managedObjectContext
que está cargada de forma managedObjectContext
. Por lo tanto, declara su managedObjectContext
como una propiedad, pero también escribe un -(NSManagedObjectContext *)managedObjectContext
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 el método de declaración de variable de instancia no. Básicamente, ivar
es la forma antigua, y @property
extiende y lo hace más elegante / 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, verá cada vez menos personas que declaren ivar
s entre las llaves, y en cambio se desplazará hacia la especificación de @property
y luego hacia @synthesize
. No puede hacer @synthesize
en su implementación sin una @property
correspondiente. 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 la desinformación que está flotando por ahí.
Si está utilizando XCode 4.4 o posterior, generará un código de síntesis de instancia de instancia para usted.
Solo tienes 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;
generará código de sintetización como
@synthesize name = _name;
y puedes acceder a la variable de instancia usando _name, es similar a declarar
NSString* _name
pero si declaras propiedad de solo lectura, te gusta
@property (nonatomic, strong, readonly) NSString *name;
generará código
@synthesize name;
o
@synthesize name = name;
Por lo tanto, debe acceder al nombre de la variable instantánea sin el prefijo "_" de la forma en que pueda escribir su propio código de síntesis, entonces el compilador generará el código para usted. puedes escribir
@synthesize name = _name;
Si está utilizando el Modern Objective-C Runtime (que es iOS 3.xo superior, o Snow Leopard de 64 bits o superior), entonces no necesita definir ivars para sus propiedades en casos como este.
Cuando @synthesize
la propiedad, el ivar se sintetizará también para usted. Esto evita el escenario "frágil-ivar". Puedes leer más sobre esto en Cocoa with Love
funciona en ambos sentidos pero si no los declaras en las llaves, no verás sus valores en el depurador en xcode.
El lenguaje de programación Objective-C: directivas de implementación de propiedades
Existen diferencias en el comportamiento de la síntesis de acceso que dependen del tiempo de ejecución (consulte también "Diferencia de tiempo de ejecución"):
Para los tiempos de ejecución heredados, las variables de instancia ya deben declararse 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 y plataformas en tiempo de ejecución" en la Guía de programación en 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.