ios - programación - Diferencia entre_y uno mismo. en Objective-C
swift ios (4)
El _
(subrayado) es simplemente una convención, como se explica en esta pregunta .
Cuando no prefieres un acceso a la propiedad con self.
, está accediendo a la variable subyacente directamente, como en la struct
. En general, solo debe hacer esto en sus métodos de inicio y en los accesores de propiedades personalizados. Esto permite que cosas como las propiedades computadas y KVC funcionen según lo previsto.
¿Hay alguna diferencia entre usar el guión bajo y usar la palabra clave self
en Objective-C cuando se llama a @property
?
Declaración de propiedad:
@property (weak, nonatomic) NSString *myString;
Llamando a @synthesize
en la propiedad:
@synthesize myString = _myString;
¿Hay alguna diferencia si quiero usarlo en mi código? ¿Cuando? En el getter / setter?
self.myString = @"test";
_myString = @"test";
Hay una sugerencia que no se menciona, el acceso mediante el subrayado es más rápido y el acceso por sí mismo es más seguro (KVC). Tal vez esto se pueda resumir cuando hay que usar cada uno.
Usted es correcto: la primera versión ( self.myString
) llama al getter / setter sintetizado y la segunda versión accede directamente a la variable de miembro privado.
Parece que estás usando ARC, así que en ese caso no hace mucha diferencia. Sin embargo, si no usa ARC, puede hacer una diferencia, ya que la asignación al miembro privado directamente no activará la lógica de retención / liberación o copia / liberación automática que se genera mediante el uso de synthesize
.
self.myString = @"test";
es exactamente equivalente a escribir [self setMyString:@"test"];
. Ambos están llamando a un método.
Podrías haber escrito ese método tú mismo. Podría verse algo como esto:
- (void)setMyString:(NSString*)newString
{
_myString = newString;
}
Debido a que @synthesize
, no tienes que molestarte en escribir ese método, simplemente puedes permitir que el compilador lo escriba por ti.
Entonces, al ver ese método, parece que llamarlo hará exactamente lo mismo que simplemente asignando un valor a la variable de instancia, ¿verdad? Bueno, no es tan simple.
En primer lugar, puedes escribir tu propio método setter. Si lo hace, se llamará a su método y podría hacer todo tipo de cosas adicionales, además de establecer la variable. En ese caso, usar self.myString =
llamaría a su método, pero hacer _myString =
no, y por lo tanto se utilizaría una funcionalidad diferente.
En segundo lugar, si alguna vez usas Key Value Observing, el compilador hace algunos trucos muy inteligentes. Detrás de las escenas, asigna una subclase a su clase y anula su método de establecimiento (ya sea uno que usted mismo escribió o uno generado por sintetizar), para realizar las llamadas a willChangeValueForKey:
que son necesarias para que Key Value Observing funcione. No necesita saber cómo funciona esto (¡aunque es bastante interesante si quiere leer algo para ir a la cama!), Pero sí necesita saber que si quiere que Key Value Observing funcione automáticamente, debe usar los métodos de configuración.
En tercer lugar, llamar al método de establecimiento incluso si confía en sintetizar para escribir uno le da flexibilidad para el futuro. Es posible que desee hacer algo adicional cada vez que se cambie un valor, y en el momento en que descubra que desea hacerlo, puede escribir manualmente un método de establecimiento. Si tiene la costumbre de usar siempre self.myString =
, entonces ¡No necesitará cambiar el resto de su código para comenzar a llamar al nuevo método!
En cuarto lugar, lo mismo se aplica a las subclases. Si alguien más tuviera que hacer una subclase de su código, si utiliza los configuradores, entonces podrían anularlos para ajustar la funcionalidad.
Cada vez que accede directamente a la variable de instancia, no está proporcionando explícitamente una manera de conectar funcionalidad adicional en ese momento. Dado que usted o alguien más querrá conectar esa funcionalidad en el futuro, vale la pena utilizar los configuradores todo el tiempo, a menos que haya una buena razón para no hacerlo.