¿Existe alguna diferencia entre una "variable de instancia" y una "propiedad" en Objective-c?
¿Existe alguna diferencia entre una "variable de instancia" y una "propiedad" en Objective-c?
No estoy muy seguro de esto. Creo que una "propiedad" es una variable de instancia que tiene métodos de acceso, pero podría pensar mal.
Una propiedad es un concepto más abstracto. Una variable de instancia es literalmente solo una ranura de almacenamiento, como una ranura en una estructura. Normalmente, nunca se supone que otros objetos accedan a ellos directamente. Una propiedad, por otro lado, es un atributo de su objeto al que se puede acceder (suena vago y se supone que así es). Por lo general, una propiedad devolverá o establecerá una variable de instancia, pero podría usar datos de varias o ninguna. Por ejemplo:
@interface Person : NSObject {
NSString *name;
}
@property(copy) NSString *name;
@property(copy) NSString *firstName;
@property(copy) NSString *lastName;
@end
@implementation Person
@synthesize name;
- (NSString *)firstName {
[[name componentsSeparatedByString:@" "] objectAtIndex:0];
}
- (NSString *)lastName {
[[name componentsSeparatedByString:@" "] lastObject];
}
- (NSString *)setFirstName:(NSString *)newName {
NSArray *nameArray = [name componentsSeparatedByString:@" "];
NSArray *newNameArray [[NSArray arrayWithObjects:newName, nil] arrayByAddingObjectsFromArray:[nameArray subarrayWithRange:NSMakeRange(1, [nameArray size]-1)]];
self.name = [newNameArray componentsJoinedByString:@" "];
}
- (NSString *)setLastName:(NSString *)newName {
NSArray *nameArray = [name componentsSeparatedByString:@" "];
NSArray *newNameArray [[nameArray subarrayWithRange:NSMakeRange(0, [nameArray size]-2)] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:newName, nil]];
self.name = [newNameArray componentsJoinedByString:@" "];
}
@end
(Nota: el código anterior tiene errores porque supone que el nombre ya existe y tiene al menos dos componentes (por ejemplo, "Bill Gates" en lugar de solo "Gates"). Sentí que corregir esas suposiciones aclararía el punto real del código. menos claro, así que solo lo señalo aquí para que nadie repita inocentemente esos errores).
Una propiedad es una forma amigable de implementar un captador/definidor para algún valor, con características y sintaxis útiles adicionales. Una propiedad puede estar respaldada por una variable de instancia, pero también puede definir el captador/establecedor para hacer algo un poco más dinámico, por ejemplo, puede definir una propiedad en minúsculas en una cadena que crea dinámicamente el resultado en lugar de devolver el valor de algún miembro. variable.
He aquí un ejemplo:
// === In your .h ===
@interface MyObject {
NSString *propertyName;
}
// ...
@property (nonatomic, retain) NSString *propertyName;
// === In your .m @implementation ===
@synthesize propertyName /* = otherVarName */;
La @property
línea define una propiedad llamada propertyName
de tipo NSString *
. Esto se puede obtener/configurar usando la siguiente sintaxis:
myObject.propertyName = @"Hello World!";
NSLog("Value: %@", myObject.propertyName);
Cuando asigna o lee, en myObject.propertyName
realidad está llamando a métodos setter/getter en el objeto.
La @synthesize
línea le dice al compilador que genere estos captadores/definidores por usted, usando la variable miembro con el mismo nombre de la propiedad para almacenar el valor (o otherVarName
si usa la sintaxis en los comentarios).
Además, @synthesize
aún puede anular uno de los captadores/definidores definiendo el suyo propio. La convención de nomenclatura para estos métodos es setPropertyName:
para el definidor y propertyName
(o getPropertyName
no estándar) para el captador. El otro aún se generará para usted.
En su @property
línea, puede definir una serie de atributos entre pares para la propiedad que pueden automatizar cosas como la seguridad de subprocesos y la administración de memoria. De forma predeterminada, una propiedad es atómica, lo que significa que el compilador envolverá @synthesiz
las llamadas get/set con bloqueos apropiados para evitar problemas de concurrencia. Puede especificar el nonatomic
atributo para desactivar esto (por ejemplo, en el iPhone en el que desea establecer de forma predeterminada la mayoría de las propiedades nonatomic
).
Hay 3 valores de atributos que controlan la gestión de la memoria para cualquier @synthesized
configurador. La primera es retain
que enviará automáticamente release
a los valores antiguos de la propiedad y retain
a los valores nuevos. Esto es muy útil.
La segunda es copy
que hará una copia de los valores pasados en lugar de conservarlos. Es una buena práctica usarlo copy
para NSString porque una persona que llama podría pasar un NSMutableString y cambiarlo debajo de usted. copy
hará una nueva copia de la entrada a la que solo usted tiene acceso.
La tercera es assign
que asigna un puntero directo sin llamar a retener/liberar en el objeto nuevo o antiguo.
Por último, también puede utilizar el readonly
atributo para desactivar el definidor de la propiedad.