iphone - ¿Qué hace exactamente @synthesize?
objective-c (8)
Como me acabo de encontrar con este problema cuando edito el código heredado, quiero hacer notas adicionales a las respuestas existentes que hay que tener en cuenta.
Incluso con una versión compiladora más nueva, a veces hace la diferencia si omite @synthesize propertyName
o no .
En el caso de que declare una variable de instancia sin subrayado mientras la sigue sintetizando, como por ejemplo:
Encabezamiento:
@interface SomeClass : NSObject {
int someInt;
}
@property int someInt;
@end
Implementación:
@implementation SomeClass
@synthesize someInt;
@end
self.someInt
accederá a la misma variable que someInt
. No usar un guion bajo para ivars no sigue las convenciones de nomenclatura, pero acabo de tener una situación en la que tuve que leer y modificar dicho código.
Pero si ahora piensas "Oye, @synthesize ya no es importante ya que usamos un compilador más nuevo" ¡estás equivocado! Luego, su clase tendrá dos ivars , a saber, someInt
más una variable autogenerada _someInt
. Por self.someInt
tanto, self.someInt
y someInt
ya no abordarán las mismas variables. Si no esperas tal comportamiento como yo, esto podría darte un dolor de cabeza para averiguarlo.
He visto el siguiente fragmento de código:
//example.h
MKMapView * mapView1;
@property (nonatomic, retain) MKMapView * mapView;
//example.m
@synthesize mapView = mapView1
Pregunta: ¿Qué relación hay entre mapView y mapView1 ? ¿Crea set y get method para mapView1 ?
Gracias !
Crea getter y setter para tu objeto. Puede acceder con algo como esto:
MKMapView* m = object.mapView;
o
object.mapView = someMapViewObject
mapView1 es el nombre del ivar en la clase, mapView es el nombre del método getter / setter.
Cuando creas una propiedad en @interface, esa propiedad se volverá automáticamente por una variable de instancia llamada _propertyName. Por lo tanto, cuando crea una propiedad denominada firstName, detrás del compilador de escena se creará una variable de instancia nombrada como _firstName de manera predeterminada. El compilador también creará el método getter y setter para usted (es decir, firstName, setFirstName).
Ahora cuando sintetizas la propiedad por @synthesize firstName, simplemente le estás diciendo al compilador que cambie el nombre de mi variable de instancia (_firstName) por firstName. Si desea cambiar el nombre de la variable de instancia respaldada por un nombre diferente, puede asignarle un nombre diferente sintetizando el nombre de la propiedad (es decir, @synthesize firstName = myFirstName); al hacer esto su propiedad se respalda con una variable de instancia llamada myFirstname.
Entonces, en resumen, la mayoría de las veces @synthesize solía cambiar el nombre de su variable de instancia respaldada por su propiedad.
De la documentación :
Utiliza la palabra clave @synthesize para decirle al compilador que debe sintetizar los métodos setter y / o getter para la propiedad si no los proporciona dentro del bloque @implementation.
En su ejemplo, mapView1
es una variable de instancia (ivar), un fragmento de memoria que pertenece a una instancia de la clase definida en example.h
example.m
. mapView
es el nombre de una propiedad . Las propiedades son atributos de un objeto que puede leerse o establecerse mediante la notación de puntos: myObject.mapView
. Una propiedad no tiene que estar basada en un ivar, pero la mayoría de las propiedades sí lo están. La declaración @property
simplemente le dice al mundo que hay una propiedad llamada mapView
.
@synthesize mapView = mapView1;
Esta línea le dice al compilador que cree un setter y getter para mapView
, y que deberían usar el ivar llamado mapView1
. Sin la parte = mapView1
, el compilador supondría que la propiedad e ivar tienen el mismo nombre. (En este caso, eso produciría un error de compilación, ya que no hay ivar llamado mapView
).
El resultado de esta declaración @synthesize
es similar a si hubiera agregado este código usted mismo:
-(MKMapView *)mapView
{
return mapView1;
}
-(void)setMapView:(MKMapView *)newMapView
{
if (newMapView != mapView1)
{
[mapView1 release];
mapView1 = [newMapView retain];
}
}
Si agrega el código a la clase usted mismo, puede reemplazar la instrucción @synthesize
con
@dynamic mapView;
Lo principal es tener una distinción conceptual muy clara entre ivars y propiedades. Son realmente dos conceptos muy diferentes.
Según la documentación de apple, @Synthesize se usa solo para cambiar el nombre de las variables de instancia. Por ejemplo
@property NSString *str;
@synthesize str = str2;
Ahora en la clase no puedes usar _str
ya que la línea anterior ha _str
el nombre de la variable de instancia a str2
@property
permite que los objetos sean utilizados por objetos en otras clases, o en otras palabras hace que el objeto sea público.
Básicamente, la sintetización crea los métodos setMapView y mapView que establecen y obtienen mapView1
@synthesize
crea un getter y un setter para la variable.
Esto le permite especificar algunos atributos para sus variables y cuando @synthesize
esa propiedad a la variable genera el getter y el setter para la variable.
El nombre de la propiedad puede ser el mismo que el nombre de la variable. A veces las personas quieren que sea diferente para usarlo en init
o dealloc
o cuando el parámetro se pasa con el mismo nombre de variable.