2011-11-16 5 views
8

Duplicar posible:
How does an underscore in front of a variable in a cocoa objective-c class work?(Objetivo C) ¿Cuál es la ventaja de hacer @synthesize myvar = _myvar (si corresponde)?

No está totalmente claro para mí (que no sean para la legibilidad del código), ¿por qué quieres crear una variable interna con un prefijo de subrayado cuando crea la propiedad.

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

E incluso si tengo que agregar algún código al captador o al colocador, no veo por qué no puedo simplemente verificar el myvar en lugar de tener que verificar _myvar y luego asignarlo a myvar.

¿Alguien me puede dar 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!

+1

Hay muchos, muchos duplicados de esta pregunta: [1] (http://stackoverflow.com/questions/3521254/) [2] (http://stackoverflow.com/questions/822487/) [3] (http://stackoverflow.com/questions/2371489) [4] (http://stackoverflow.com/questions/5582448/) [5] (http://stackoverflow.com/questions/837559/) [6] (http://stackoverflow.com/questions/6064283 /) [y más ...] (http://stackoverflow.com/search?q=objc+property+underscore) –

Respuesta

8

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.

Usted puede sintetizar la propiedad y a la variable x usando:

@synthesize y = x; 

Ahora sobre el guión.

Es una práctica común usar un prefijo de guión bajo para variables de instancia, para evitar colisiones de nombres o advertencias de compilador (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 utilizar el prefijo de subrayado para las variables de instancia, usted es libre de utilizar el nombre sin el subrayado en los argumentos del método, las variables de pila, etc.

Pero cuando se utiliza una propiedad, por lo general no desea que el usuario para escribir un guion bajo

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

Esto es por lo que escribe:

@synthesize x = _x; 

Tomemos un ejemplo:

@interface Test: NSObject 
{ 
    int x; 
} 

@property(readonly) int x; 

@end 

Esto es bastante común ...Pero ahora imagine 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 compilador, esto también puede generar una advertencia (-Wshadow).

Si utiliza un prefijo de guión para su variable de instancia, todo es simple:

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

    return self; 
} 

No hay ningún conflicto, ninguna colisión de nombres, mejoramiento de la lectura ... Sólo una buena manera ...

+0

Awesome, thanks !!!!! Este fue el tipo de razón que estaba buscando, de hecho es crucial en muchos casos. – user1006198

+0

¡De nada! :) También tenga en cuenta que Apple prohíbe el uso del prefijo de subrayado en las pautas de codificación ObjC para los métodos. No se aplica a las variables de instancia. – Macmade

+0

No creo que alguien de C/C++/Java u otro idioma conozca la diferencia entre una propiedad y una variable de instancia.Sí, todos sabemos qué variable de instancia es, pero la palabra ** propiedad ** no parece ser familiar, excepto para los tipos OC :). –

9

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 de poner en el _ por accidente.

+0

muy bien puesto Kenny; No consideré que la razón por la que tiene getter y setter es evitar acceder al ivar directamente :) – user1006198

1

Cuando se utiliza una propiedad de uno mismo, es fácil olvidar el "auto":

[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 forma idéntica, los últimos casos se compile sin quejarse y parezca que funciona ... hasta que no lo haga, y obtendrá un extraño error de borde muy difícil de reproducir.

Si el ivar tiene un nombre ligeramente diferente, digamos con un _ adjunto, el compilador lo parará y le hará decidir explícitamente: ¿quiero referirme a la propiedad aquí, o al ivar directamente?

(Dicho todo esto, soy perezoso y, a menudo hago @synthesize field;, y reemplazarlo después con @synthesize field = field_; cuando realmente necesito el Ivar distinta, por ejemplo cuando es hora de costumbre-setter-escritura.)

+0

gracias por su respuesta! – user1006198

Cuestiones relacionadas