objective c - usar - ¿Cómo funciona un guión bajo al frente de una variable en una clase de cacao objetivo-c?
programacion en objective c (9)
He visto en algunos ejemplos de iPhone que los atributos han usado un guión bajo _ en frente de la variable. Alguien sabe que significa esto? O cómo funciona?
Un archivo de interfaz que estoy usando se ve así:
@interface MissionCell : UITableViewCell {
Mission *_mission;
UILabel *_missionName;
}
@property (nonatomic, retain) UILabel *missionName;
- (Mission *)mission;
No estoy seguro de qué hace exactamente lo anterior, pero cuando intento establecer el nombre de la misión como:
aMission.missionName = missionName;
Me sale el error:
solicitud de miembro ''nombre de misión'' en algo que no sea una estructura o unión
El único propósito útil que he visto es diferenciar entre variables locales y variables de miembros como se indicó anteriormente, pero no es una convención necesaria. Cuando se combina con @property, aumenta la verbosidad de las sentencias sintetizar - @synthesize missionName = _missionName;
, y es feo en todas partes.
En lugar de usar el guión bajo, solo use nombres descriptivos de variables dentro de métodos que no entren en conflicto. Cuando deben entrar en conflicto, el nombre de la variable dentro del método debe sufrir un guión bajo, no la variable miembro que puede ser utilizada por múltiples métodos . El único lugar común que esto es útil es en un setter o en un método init. Además, hará que la declaración @synthesize sea más concisa.
-(void)setMyString:(NSString*)_myString
{
myString = _myString;
}
Edición: con la última función del compilador de auto-síntesis, ahora uso el guión bajo para el ivar (en la rara ocasión que necesito usar un ivar para que coincida con lo que hace la auto-síntesis).
En realidad, no significa nada, es solo una convención que algunas personas usan para diferenciar las variables de los miembros de las variables locales.
En cuanto al error, parece que aMisión tiene el tipo incorrecto. ¿Cuál es su declaración?
Es solo una convención para la legibilidad, no hace nada especial para el compilador. Verá que las personas lo usan en variables de instancia privadas y nombres de métodos. Apple realmente recomienda no usar el guión bajo (si no estás siendo cuidadoso podrías anular algo en tu superclase), pero no deberías sentirte mal por ignorar ese consejo. :)
Este parece ser el elemento "maestro" para preguntas sobre self.variableName vs. _variablename. Lo que me sorprendió fue que en el .h, tuve:
...
@interface myClass : parentClass {
className *variableName; // Note lack of _
}
@property (strong, nonatomic) className *variableName;
...
Esto lleva a que self.variableName y _variableName sean dos variables distintas en .m. Lo que necesitaba era:
...
@interface myClass : parentClass {
className *_variableName; // Note presence of _
}
@property (strong, nonatomic) className *variableName;
...
Luego, en la clase ''.m, self.variableName y _variableName son equivalentes.
Lo que todavía no tengo claro es por qué muchos ejemplos aún funcionan, incluso si esto no se hace.
Rayo
Esto es solo para la convención de nomenclatura de las propiedades de síntesis.
Cuando sintetice variables en el archivo .m, Xcode le proporcionará automáticamente la inteligencia de la variable.
Falta de las otras respuestas es que el uso de _variable
evita que escriba innecesariamente variable
y acceda a la propiedad ivar en lugar de a la propiedad (supuestamente prevista).
El compilador te obligará a utilizar ya sea self.variable
o _variable
. El uso de guiones bajos hace que sea imposible escribir variable
, lo que reduce los errores del programador.
- (void)fooMethod {
// ERROR - "Use of undeclared identifier ''foo'', did you mean ''_foo''?"
foo = @1;
// So instead you must specifically choose to use the property or the ivar:
// Property
self.foo = @1;
// Ivar
_foo = @1;
}
Si usa el prefijo de subrayado para sus ivars (que no es más que una convención común, pero útil), entonces necesita hacer 1 cosa adicional para que el descriptor de acceso generado automáticamente (para la propiedad) sepa qué ivar usar. Específicamente, en su archivo de implementación, su synthesize
debería verse así:
@synthesize missionName = _missionName;
Más genéricamente, esto es:
@synthesize propertyName = _ivarName;
Tener un guión bajo no solo permite resolver tus ivars sin recurrir al uso de la sintaxis de self.member, sino que hace que tu código sea más legible ya que sabes cuándo una variable es un ivar (debido a su prefijo de subrayado) o un argumento de miembro (sin guión bajo) )
Ejemplo:
- (void) displayImage: (UIImage *) image {
if (image != nil) {
// Display the passed image...
[_imageView setImage: image];
} else {
// fall back on the default image...
[_imageView setImage: _image];
}
}
en lugar de guion bajo, puede usar el nombre de auto.variable o puede sintetizar la variable para usar la variable o punto de venta sin guion bajo.