¿Hay alguna diferencia entre una “variable de instancia” y una “propiedad” en Objective-c?

¿Hay 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 que está mal.

Una propiedad es un concepto más abstracto. Una variable de instancia es literalmente solo un espacio de almacenamiento, como un espacio en una estructura. Normalmente, se supone que otros objetos nunca deben acceder 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 debe). Por lo general, una propiedad devolverá o establecerá una variable de instancia, pero podría usar datos de varios o ninguno. 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 ya que supone que el nombre ya existe y tiene al menos dos componentes (por ejemplo, “Bill Gates” en lugar de solo “Gates”). Sentí que corregir esos supuestos sería el verdadero punto del código menos claro, así que solo lo estoy señalando aquí, así que nadie repite inocentemente esos errores).

Una propiedad es una forma amigable de implementar un getter / setter por algún valor, con características adicionales útiles y syntax. Una propiedad puede respaldarse con una variable de instancia, pero también puede definir getter / setter para hacer algo un poco más dynamic, por ejemplo, puede definir una propiedad de lowerCase en una cadena que crea dinámicamente el resultado en lugar de devolver el valor de algún miembro variable.

Aquí hay un ejemplo:

 // === In your .h === @interface MyObject { NSString *propertyName; } // ... @property (nonatomic, retain) NSString *propertyName; // === In your .m @implementation === @synthesize propertyName /* = otherVarName */; 

La línea @property define una propiedad llamada propertyName de tipo NSString * . Esto se puede obtener / configurar usando la siguiente syntax:

 myObject.propertyName = @"Hello World!"; NSLog("Value: %@", myObject.propertyName); 

Cuando asigna o lee desde myObject.propertyName , realmente llama a los métodos setter / getter en el objeto.

La línea @synthesize le dice al comstackdor que genere estos getter / setters por usted, usando la variable miembro con el mismo nombre de la propiedad para almacenar el valor (u otherVarName si usa la syntax en los comentarios).

Junto con @synthesize , aún puede anular uno de los getter / setters definiendo el suyo. La convención de nomenclatura para estos métodos es setPropertyName: para setter y propertyName (o getPropertyName , no estándar) para el getter. El otro se generará para usted.

En su línea @property puede definir una cantidad de atributos en parens para la propiedad que puede automatizar cosas como seguridad de subprocesos y administración de memoria. Por defecto, una propiedad es atómica, lo que significa que el comstackdor ajustará @synthesiz ed get / set llamadas con lockings apropiados para evitar problemas de concurrencia. Puede especificar el atributo no nonatomic para deshabilitar esto (por ejemplo, en el iPhone que desea que la mayoría de las propiedades no sean nonatomic ).

Hay 3 valores de atributo que controlan la gestión de memoria para cualquier @synthesized . El primero es retain lo que automáticamente enviará la release a los valores antiguos de la propiedad, y retain a los nuevos valores. Esto es muy útil

El segundo es una copy que hará una copia de los valores pasados ​​en lugar de retenerlos. Es una buena práctica usar 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.

El tercero es assign que hace una asignación de puntero recto sin llamar retención / liberación en el objeto viejo o nuevo.

Por último, también puede usar el atributo de readonly para deshabilitar el establecimiento de la propiedad.

Utilizo propiedades para la parte de la interfaz, donde las interfaces del objeto con otros objetos y variables de instancia son cosas que necesita dentro de su clase, nadie más que usted debe ver y manipular esos elementos.

De forma predeterminada, una propiedad de lectura respaldará una variable de instancia, que el comstackdor sintetizará de nuevo automáticamente.

Una variable de instancia es una variable que existe y mantiene su valor durante la vida del objeto. La memoria utilizada para las variables de instancia se asigna cuando el objeto se crea por primera vez (a través de alloc) y se libera cuando el objeto se desasigna.

A menos que especifique lo contrario, la variable de instancia sintetizada tiene el mismo nombre que la propiedad, pero con un prefijo de subrayado. Para una propiedad llamada firstName, por ejemplo, la variable de instancia sintetizada se llamará _firstName.

Anteriormente las personas usaban propiedades públicamente y ivars para uso privado, pero desde hace varios años, también puedes definir propiedades en @implementation para usarlas de forma privada. Pero aún utilizaría ivars cuando sea posible, ya que hay menos letras para escribir, y se ejecuta más rápido de acuerdo con este artículo . Tiene sentido, ya que las propiedades tienen la intención de ser “pesadas”: se supone que se accede desde los captadores / definidores generados o los escritos manualmente.

Sin embargo, en los códigos recientes de Apple, ya no se usan ivars. Supongo que es más como objc que como C/C++ , además de que es más fácil usar propiedades con assign , nullable , etc.