Cuándo usar variables de instancia y cuándo usar propiedades

Al usar las propiedades de Objective-C, ¿puede dejar de crear variables de instancia por completo o las variables de instancia explícitas (no las sintetizadas por las propiedades) siguen teniendo un propósito en el que las propiedades serían inapropiadas?

preguntado el 03 de mayo de 12 a las 14:05

4 Respuestas

¿Puedes dejar de crear variables de instancia por completo?

No, no puedes (en cierto sentido). Lo que puedes hacer es dejar de declararlos si tienes propiedades. Si sintetiza una propiedad y no ha declarado instvar, se declarará por usted, por lo que está creando una variable de instancia, pero no explícitamente.

¿siguen teniendo un propósito en el que las propiedades serían inapropiadas?

Solía ​​ser el consejo crear propiedades para todo porque tener propiedades sintetizadas hace casi todas las retenciones y liberaciones por usted. Sin embargo, con ARC esa razón para usar propiedades para envolver la administración de memoria desapareció. El consejo ahora (para ARC) es, creo, usar propiedades para declarar su interfaz externa, pero use variables de instancia directa donde la variable sea parte del estado interno del objeto.

Esa es una buena razón para adoptar ARC: las propiedades vuelven a su verdadero propósito solo de ser parte de la API de la clase y ya no es necesario usarlas como una forma pirateada de ocultar el trabajo de administración de memoria.

Editar

Una cosa más: ahora puede declarar variables de instancia en el @implementation por lo que ahora no hay necesidad de filtrar ningún detalle de implementación en el @interface. es decir

@implementation MyClass
{
    NSString* myString;
}
// method definitions
@end

Y estoy bastante seguro de que también funciona en categorías. - ver comentario abajo

contestado el 03 de mayo de 12 a las 14:05

no puede agregar ivars y propiedades a las categorías, ya que objc-runtime solo permite agregar ivars durante el registro de clase. No puede modificar un diseño de memoria de una clase después de que se haya registrado con el tiempo de ejecución. - Jonathan Cichón

puede, sin embargo, agregue ivars a una extensión de clase (estrechamente relacionada, pero diferente de una categoría) - Sean

@Jonathan Cichon: Gracias por eso, acabo de probarlo y resulta que tiene razón sobre las variables de instancia pero está equivocado sobre las propiedades. Puedes agregar propiedades pero no puedes @synthesize ellos. - jeremyp

@JonathanCichon, las propiedades no sintetizadas en categorías son muy útiles y comunes. Solo tiene que escribir un getter/setter personalizado. Vea esta publicación de blog para mi uso más común de esta técnica: www.oleb.net/blog/2011/05/… - rober napier

@Jonathan Cichon: Me temo que es un malentendido de propiedades. Una propiedad es parte de la API, la implementación depende de usted y @synthesize simplemente automatiza uno de los patrones de implementación más comunes al agregar un conjunto estándar de accesores. No hay nada que le impida definir sus propios accesorios diferentes. - jeremyp

Recomiendo declarar todo como propiedades y evitar los ivars manuales por completo. No hay ninguna ventaja real en la creación manual de ivars. Declara propiedades públicas en tu encabezado @interface, declare propiedades privadas en una extensión de clase privada en su archivo .m.

Para algunos de los puntos de JeremyP, el uso interno de accesores todavía tiene un valor significativo bajo ARC, aunque la gestión de la memoria ya no es una preocupación importante. Asegura que KVO funcione correctamente, subclase mejor, admita configuradores personalizados (particularmente para cosas como NSTimer), admite captadores personalizados (como para la creación de instancias perezosas), etc. Es extremadamente propenso a errores tener una combinación de accesores e ivars. Es demasiado fácil olvidar a qué necesita acceder y de qué manera. La consistencia es el sello distintivo de un buen ObjC.

Si absolutamente debe declarar un ivar por alguna razón, entonces debe hacerlo en el @implementation bloque como señala JeremyP.


ACTUALIZACIÓN (octubre de 2013):

La guía de Apple (De Programación con Objective-C: Encapsulación de datos):

La mayoría de las propiedades están respaldadas por variables de instancia

En general, debe usar métodos de acceso o sintaxis de puntos para el acceso a la propiedad incluso si está accediendo a las propiedades de un objeto desde su propia implementación, en cuyo caso debe usar self:

...

La excepción a esta regla es cuando se escriben métodos de inicialización, desasignación o acceso personalizado, como se describe más adelante en esta sección.

Respondido el 20 de junio de 20 a las 10:06

KVO no es importante para algo que es solo interno. La subclasificación tampoco. Nada que sea parte de la implementación de una clase debe filtrarse, ni siquiera a las subclases. Este es el sello distintivo de una buena programación orientada a objetos. - jeremyp

A pesar de KVO (aunque la autoobservación se usa ocasionalmente), dado que a menudo necesita accesores en propiedades privadas (ejecución diferida, seguridad de subprocesos, etc.), y usarlos es simple y económico, siempre debe usarlos excepto cuando hay un fuerte razón para no hacerlo (es decir, dealloc). A veces, el uso de ivars y, a veces, el uso de accesores es propenso a errores y difícil de auditar para verificar su corrección. - rober napier

¿Cómo se crea una instancia perezosa sin una variable de instancia? Repetiré: la línea oficial como se informa en la lista de Apple es usar variables de instancia para el estado interno cuando tiene ARC pero usar propiedades para todo si está usando el conteo de referencia tradicional. - jeremyp

@JeremyP, solo curiosidad, ¿dónde están los documentos de Apple con respecto a esto? - Alex311

@ Alex311 Creo que nunca he visto nada oficial de Apple. Los documentos a los que me refería eran un correo electrónico enviado a la lista de Objective-C por un empleado de Apple. - jeremyp

Esta pregunta fue abordada antes aquí

Cuando se utiliza synthesize las variables de instancia se manejan y se instancian por usted. Si está utilizando Lion con la nueva versión de XCode, también eche un vistazo a las diversas propiedades en ARC en Transición a ARC

contestado el 23 de mayo de 17 a las 12:05

No creo que sea la misma pregunta, pero actualicé mi pregunta para que sea más clara. - Besi

siempre se puede acceder a las propiedades desde el exterior. Entonces, si desea que una variable solo se lea desde dentro de una clase, aún debe declarar un iVar. También accediendo a un ivar público con object->ivar es un poco más rápido que usar una llamada de método.

contestado el 03 de mayo de 12 a las 14:05

Esto no es verdad. ¿Qué sucede si declaró la propiedad en el archivo .m? - Martin

tiene razón, puede ocultar la propiedad por completo, pero no puede acceder a ella desde fuera de su archivo m, por ejemplo, una subclase. - Jonathan Cichón

@Martin: como la propiedad se implementa como un par de métodos, siempre está disponible en tiempo de ejecución, sin importar dónde se haya declarado. - jeremyp

@Martin: ¿de qué parte no estabas al tanto? ¿Que las propiedades son realmente un método setter y getter o que los métodos son siempre públicos de manera efectiva? - jeremyp

Mientras agarraba directamente los ivares internos con -> es más rápido que un setter, casi nunca es la respuesta correcta. En el momento en que esté haciendo ese tipo de optimización, casi siempre hay una mejor optimización que debería haber hecho en su lugar. Esta es una técnica muy peligrosa y no algo para uso general. - rober napier

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.