(Objetivo C) ¿cuál es la ventaja de hacer @synthesize myvar = _myvar (si hay alguno)?

Posible duplicado:
¿Cómo funciona un guión bajo al frente de una variable en una clase de cocoa objective-c?

No es completamente claro para mí (aparte de la legibilidad del código), por qué quieres crear una variable interna con un prefijo de guión bajo cuando creas la propiedad.

Como todo se maneja internamente, ¿por qué molestarse en hacerlo, ya que no agregamos ningún código al getter y al setter?

E incluso si tengo que agregar un código al getter o al setter, no veo por qué no puedo simplemente hacer check en myvar en lugar de tener que verificar _myvar y luego asignarlo a myvar.

¿Alguien puede darme alguna explicación, aparte de “hacerlo porque eso es lo que todos hacen”? Me gustaría entender la razón de esta práctica (que parece ser bastante común incluso si no hay un código personalizado para el getter y el setter).

¡Gracias!

Una propiedad Objective-C generalmente tiene una variable de instancia de respaldo (supongo que conoce la diferencia entre una propiedad y una variable de instancia).

La propiedad puede tener un nombre diferente al de la variable de instancia.

Por ejemplo, puede tener una variable de instancia llamada x , con una propiedad llamada y .

Puede sintetizar la propiedad y de la variable x usando:

 @synthesize y = x; 

Ahora sobre el guión bajo.

Es una práctica común utilizar un prefijo de subrayado para variables de instancia, para evitar colisiones de nombres, o advertencias de comstackdor (variable sombreada), cuando se tiene, por ejemplo, un argumento de método con el mismo nombre que una variable de instancia.

El prefijo de subrayado también deja en claro que se refiere a una variable de instancia.

Al usar el prefijo de subrayado para las variables de instancia, puede usar el nombre sin el guión bajo en los argumentos del método, variables de stack, etc.

Pero cuando se usa una propiedad, generalmente no se desea que el usuario escriba un guión bajo.

Por lo tanto, normalmente tiene una propiedad x para una variable de instancia _x .

Es por eso que escribes:

 @synthesize x = _x; 

Tomemos un ejemplo:

 @interface Test: NSObject { int x; } @property( readonly ) int x; @end 

Esto es bastante común … Pero ahora imagina esto en la implementación:

 - ( id )initWithX: ( int )x {} 

Tenemos una colisión de nombres.

Dentro de nuestro método, x se referirá al argumento del método. Y no hay una manera bonita de acceder a la variable de instancia x .

Dependiendo de las banderas de advertencia de su comstackdor, esto también puede generar una advertencia ( -Wshadow ).

Si usa un prefijo de subrayado para su variable de instancia, todo es simple:

 - ( id )initWithX: ( int )x { if( ( self = [ super init ] ) ) { _x = x; } return self; } 

Sin conflictos, sin colisión de nombres, lectura mejorada … Solo una buena manera …

Me lo he preguntado muchas veces yo mismo. Interesado en la respuesta de otras personas, pero una de las razones que he encontrado es que te obliga a darte cuenta si estás accediendo directamente al ivar cuando deberías estar usando el getter / setter.

self.myvar = @"blah"; y _myvar = @"blah";

vs

self.myvar = @"blah"; y myvar = @"blah";

Es fácil dejar el self. por accidente … es mucho más difícil poner el _ por accidente.

Al usar una propiedad de sí mismo, es fácil olvidarse del “sí mismo”:

 [self.field doSomething]; // what you probably want [self setField:someObject]; // also kosher self.field = someObject; // ditto, although not my style 

vs.

 [field doSomething] // might work.. but will bite you eventually field = someObject; // almost certainly wrong anywhere outside a custom setter 

Si la propiedad y el ivar se nombran de manera idéntica, los últimos casos se comstackrán sin queja y parecerán que funcionan … hasta que no lo hagan, y obtendrás un extraño error de borde muy difícil de reproducir.

Si el ivar tiene un nombre ligeramente diferente, por ejemplo con un final adjunto, el comstackdor lo detendrá y lo hará decidir explícitamente: ¿quiero referirme a la propiedad aquí, o al ivar directamente?

(Todo lo dicho, soy flojo y a menudo hago el @synthesize field; y lo reemplazo más adelante con @synthesize field = field_; cuando realmente necesito el ivar distinto, por ejemplo, cuando es el tiempo de redacción del iniciador de la configuración).