Objective-C Sucintamente Propiedades

Ahora que hemos explorado qué tipos de datos están disponibles, podemos hablar de cómo usarlos de manera productiva. Aprendimos cómo declarar propiedades en Hello, Objective-C, pero este capítulo profundiza en los matices detrás de las propiedades públicas y las variables de instancia. Primero, veremos rápidamente la sintaxis básica de las propiedades y las variables de instancia, y luego analizaremos cómo usar los atributos de comportamiento para modificar los métodos de acceso..


Declarar propiedades

Las propiedades se pueden declarar en una interfaz usando el @propiedad directiva. Como una revisión rápida, echemos un vistazo a la Persona.h archivo que creamos en el capítulo Hello, Objective-C:

#importar  Persona de la interfaz: NSObject @property (copy) NSString * name; @fin

Esto declara una propiedad llamada nombre de tipo NSString. los (dupdo) atributo le dice al tiempo de ejecución qué hacer cuando alguien intenta establecer el valor de nombre. En este caso, crea una copia independiente del valor en lugar de apuntar al objeto existente. Hablaremos más sobre esto en el siguiente capítulo, Gestión de la memoria..


Implementando propiedades

En Hello, Objective-C, utilizamos el @sintetizar Directiva para crear automáticamente métodos getter y setter. Recuerde que el método getter es simplemente el nombre de la propiedad, y el método setter predeterminado es escoger un nombre:

#import "Person.h" @implementation Person @synthesize name = _name; @fin

Pero, también es posible crear manualmente los métodos de acceso. Hacer esto manualmente ayuda a entender qué @propiedad y @sintetizar están haciendo detrás de las escenas.

Ejemplo de código incluido: ManualProperty

Primero, agregue una nueva propiedad a la Persona interfaz:

@property (copia) NSString * nombre; @property unsigned int age;

Tenga en cuenta que estamos almacenando años como un tipo de datos primitivo (no un puntero a un objeto), por lo que no necesita un asterisco antes del nombre de la propiedad. De nuevo en Persona.m, Definir los métodos de acceso explícitamente:

- (unsigned int) age return _age;  - (void) setAge: (unsigned int) age _age = age; 

Esto es exactamente lo que @sintetizar Habría hecho por nosotros, pero ahora tenemos la oportunidad de validar los valores antes de que se asignen. Sin embargo, nos falta una cosa: la _años Instancia variable. @sintetizar creó automáticamente un _nombre Ivar, lo que nos permite renunciar a esto por el nombre propiedad.


Variables de instancia

Las variables de instancia, también conocidas como ivars, son variables destinadas a ser utilizadas dentro de la clase. Pueden ser declarados dentro de llaves después de cualquiera de los dos. @interfaz o @implementación directivas Por ejemplo, en Persona.h, Cambie la declaración de interfaz a lo siguiente:

@interface Person unsigned int _age; 

Esto define una variable de instancia llamada _años, por lo que esta clase ahora debe compilar con éxito. Por defecto, las variables de instancia declaradas en una interfaz son protegido. La definición de clase C # equivalente sería algo como:

clase Persona protegido uint _age; 

Los modificadores de alcance de Objective-C son los mismos que en C #: las variables privadas solo son accesibles para la clase contenedora, las variables protegidas son accesibles para todas las subclases y las variables públicas están disponibles para otros objetos. Puede definir el alcance de las variables de instancia con el @privado, @protegido, y @público directivas dentro de @interfaz, como se demuestra en el siguiente código:

Persona de la interfaz: NSObject @private NSString * _ssn; @protected unsigned int _age; trabajo @public NSString *; 

Los ivars públicos están en realidad un poco fuera de las normas de Objective-C. Una clase con variables públicas actúa más como una estructura C que una clase; en lugar de la sintaxis de mensajería habitual, debe utilizar el -> operador de puntero Por ejemplo:

Persona * franco = [[Asignación de persona] init]; frank-> trabajo = @ "astronauta"; NSLog (@ "% @", frank-> trabajo); // NO: [trabajo franco];

Sin embargo, en la mayoría de los casos, querrá ocultar los detalles de la implementación utilizando un @propiedad Declaración en lugar de variables de instancia pública. Además, como las variables de instancia son detalles técnicos de implementación, muchos programadores prefieren mantener todos Variables de instancia privadas. Con esto en mente, ivars declaró en @implementación Son privados por defecto. Entonces, si fueras a mover el _años declaración a Persona.m en lugar del encabezado:

Persona de implementación unsigned int _age; 

_años sería ámbito como privado variable. Tenga esto en cuenta cuando trabaje con variables de instancia en subclases, ya que los diferentes valores predeterminados para la declaración de interfaz versus implementación pueden ser confusos para los recién llegados a Objective-C.

Personalización de accesores

Pero basta de variables de instancia; volvamos a las propiedades. Los métodos de acceso se pueden personalizar utilizando varios atributos de declaración de propiedad (por ejemplo,., (dupdo)). Algunos de los atributos más importantes son:

  • getter = getterName - Personaliza el nombre del método de acceso getter. Recuerde que el valor predeterminado es simplemente el nombre de la propiedad..
  • setter = setterName - Personaliza el nombre del método de acceso setter. Recuerde que el valor predeterminado es conjunto seguido del nombre de la propiedad (por ejemplo,., escoger un nombre ).
  • solo lectura - Haga que la propiedad sea de solo lectura, lo que significa que solo se sintetizará un captador. Por defecto, las propiedades son de lectura-escritura. Esto no puede ser usado con el setter atributo.
  • no atómico - Indique que los métodos de acceso no necesitan ser seguros para subprocesos. Las propiedades son atómicas por defecto, lo que significa que Objective-C usará un bloqueo / retención (descrito en el siguiente capítulo) para devolver el completar Valor de un getter / setter. Tenga en cuenta, sin embargo, que esto hace no garantiza la integridad de los datos en todos los subprocesos, simplemente que los captadores y definidores serán atómicos. Si no estás en un entorno de subprocesos, las propiedades no atómicas son mucho más rápidas.

Un caso de uso común para personalizar los nombres de getter es para las convenciones de nombres booleanos. A muchos programadores les gusta anteponer es a nombres de variables booleanas. Esto es fácil de implementar a través de adquiridor atributo:

@property (getter = isEmployed) BOOL empleado;

Internamente, la clase puede usar el empleado variable, pero otros objetos pueden usar el está empleado y setEmployed Accessors para interactuar con el objeto:

Persona * franco = [[Asignación de persona] init]; [frank setName: @ "Frank"]; [conjunto franco desplegado: sí]; if ([frank isEmployed]) NSLog (@ "Frank está empleado");  else NSLog (@ "Frank está desempleado"); 

Muchos de los otros atributos de propiedad se relacionan con la administración de memoria, que se analizarán en la próxima sección. También es posible aplicar múltiples atributos a una sola propiedad separándolos con comas:

@property (getter = isEmployed, readonly) BOOL empleado;

Sintaxis de puntos

Además de los métodos de obtención / establecimiento, también es posible usar la notación de puntos para acceder a las propiedades declaradas. Para los desarrolladores de C #, esto debería ser mucho más familiar que la sintaxis de mensajería de corchete cuadrado de Objective-C:

Persona * franco = [[Asignación de persona] init]; frank.name = @ "Frank"; // Igual que [frank setName: @ "Frank"]; NSLog (@ "% @", frank.name); // Igual que [nombre franco];

Tenga en cuenta que esto es solo una conveniencia, se traduce directamente a los métodos de obtención / establecimiento descritos anteriormente. Notación de puntos no poder ser utilizado para métodos de ejemplo.


Resumen

Las propiedades son un aspecto integral de cualquier lenguaje de programación orientado a objetos. Son los datos con los que operan los métodos. los @propiedad La directiva es una forma conveniente de configurar el comportamiento de una propiedad, pero no hace nada que no se pueda hacer mediante la creación manual de los métodos de obtención y establecimiento..

En el siguiente capítulo, veremos en detalle cómo se almacenan las propiedades en la memoria, así como algunos atributos de propiedades nuevos para controlar este comportamiento. Después de eso, nos adentraremos en los métodos que completan las herramientas centrales orientadas a objetos de Objective-C..

Esta lección representa un capítulo de Objective-C Sucintamente, un libro electrónico gratuito del equipo de Syncfusion.