2009-05-07 7 views
30

Duplicar posible:
How does an underscore in front of a variable in a cocoa objective-c class work?¿Cuándo haces un guion bajo frente a una variable de instancia?

He visto esto en Apple, en el interior UIPickerView.h:

id<UIPickerViewDataSource> _dataSource; 

por qué de que subrayan allí? ¿Tiene un significado especial? ¿Una convención de la que debo saber?

+3

http://stackoverflow.com/questions/822487/how-does-un-underscore-in-front-of-a-variable-in-a-cocoa-objective-c-class-work – Chuck

Respuesta

34

Mucha gente usa esto para variables privadas, para diferenciar entre variables privadas y variables públicas dentro de un objeto.

Es una forma completamente opcional de trabajar.

+24

Apple reserva variables comenzando con _ para sus propios usos. No lo hagas –

+2

Haría +1 gs de comentario si pudiera. – Abizern

+0

@gs (o Abizern): ¿Tiene una referencia para esto? Sé que el compilador utiliza el nombre estándar C, lo que agregará un guión bajo, pero eso no le impide hacer esto en su propia base de código ... –

2

A veces se usa para denotar variables privadas. De manera más general, solo significa que "esta variable es diferente de alguna manera".

1

Generalmente se trata de indicar que una variable no debe ser tocada directamente por un desarrollador. No es realmente un requisito, pero es una buena práctica si no puede evitar tener una variable pública en una clase que no le moleste.

+1

Existe la palabra clave @private para variables de instancia en una implementación de clase que hace esto. – Abizern

8

Como ya se ha dicho, _someVar solía decir que una variable era privada. Era una simple cuestión de convención y realmente no importa.

Otro uso, realizar un viaje en la máquina de retorno en C a _function() representaba una función que no era portátil en la plataforma y __function() representaba una función que no era portátil para el compilador. Por lo tanto, en la biblioteca C estándar, a veces verá una variable con un _ o __ enfrente del nombre, esto es lo que representan esas funciones.

+0

Supongo que de ahí viene _asm y __asm? –

28

Lo que está viendo es el uso de subrayados para distinguir entre variables de instancia y propiedades. Así que una declaración de clase podría ser:

@interface Foo { 
    NSString* _label; 
    .... 
} 

@property (nonatomic, retain) NSString* label; // notice: no underline 

Luego, en el archivo de implementación que tendría:

@synthesize label=_label; // the property is matched with the ivar 

Ahora, cuando dentro de la aplicación, si desea acceder a la variable de instancia directamente es posible que utilices _label pero para ir a través de los métodos de acceso a la propiedad (que se encargan de retener/liberar y un montón de otras tareas de contabilidad) se usaría self.label. Desde el exterior, siempre desearía ir a través de la propiedad {object}.label.

La otra forma es hacerlo sin el subrayado y el uso justo:

NSString* label; 
@property (nonatomic, retain) NSString* label; 
... 
@synthesize label; 

Funciona de la misma, pero entonces se podría confundir a alguien que lee el código y tratando de no perder de vista label vs self.label. Personalmente encuentro que la convención de Apple (con subrayados) es un poco más fácil de leer, pero es una cuestión de preferencia.

+2

Gracias. Personalmente, no me agrada ese subrayado;) – Thanks

+0

No del todo: las personas usan "_" en cualquier número de lenguajes de programación, y lo hicieron en Objective-C mucho antes de que se agregaran las propiedades. Este es solo un uso posible, pero hay muchos otros.Algunas personas prefieren usar "_" para todas las variables de instancia, o solo variables privadas, o lo que sea. Personalmente, tampoco es mi estilo. –

+2

Acabo de pasar siglos rastreando un problema de administración de memoria debido a que una variable no se retenía porque estaba usando el temporizador en lugar de self.timer. Después de esta experiencia, recomiendo encarecidamente el uso de un _ delante de todas las variables privadas – Casebash

2

puede ser que ... (memoria trotar) ...

Recuerdo vagamente la lectura de un documento de ADC explicando que Apple se reserva el uso de variables miembro de subrayado prefijada?y que se desaconseja a los desarrolladores de terceros utilizar esta convención para evitar colisiones.

| K <

+0

colisiones? Cuando subclases? Eso podría tener sentido. – Thanks

+6

Incorrecto. Son los nombres de los métodos prefijados bajo la barra que están reservados, no los nombres de las variables de instancia. (Objective-C no usa el término "miembro") –

+0

@chris: muchas gracias por aclarar esto. – kent

2

I utilizar guiones para indicar que una variable es un miembro, similar al prefijo 'm' en notación húngara (que notación abominé a fondo, pero que es otra historia). Seguro que tiene editores de códigos de color estos días, pero mi opinión es que el prefijo hace pensar en la variable como miembro/instancia uno antes de lo escribe, no solo en algún momento después cuando el editor de color lo codifica por colores.

1

decido utilizar guiones para Ivars, ya menudo encontramos la siguiente situación:

@interface MyClass:NSObject 
{ 
    NSUInteger count; 
} 

@property(nonatomic) NSUInteger count; 

-(id) initWithCount(NSUInteger) count; 


@end 

(...) 

@implementation MyClass 
@synthesize count; 

-(id) initWithCount(NSUInteger) count 
{ 
    if((self = [super init])){ 
     self.count = count; // Parameter name collides with ivar name! 
    } 
    return self; 
} 

@end 

por lo que esto:

@interface MyClass:NSObject 
{ 
    NSUInteger _count; 
} 

@property(nonatomic) NSUInteger count; 

-(id) initWithCount(NSUInteger) count; 

@end 

(...) 

@implementation MyClass 
@synthesize count = _count; 

-(id) initWithCount(NSUInteger) count 
{ 
    if((self = [super init])){ 
     _count = count; // No name collision 
    } 
    return self; 
} 

@end 

Por supuesto, podría cambiar alternativamente el nombre del parámetro a "newCount" o "aCount" (odio eso). Creo que es una cuestión de gusto.

Cuestiones relacionadas