2012-01-05 13 views
5

Me encuentro con un escenario bastante común en Objective-C donde paso una variable a un método init y luego quiero asignarlo a una variable de instancia del mismo nombre. Sin embargo, no he encontrado una forma de delimitar las variables para aclarar cuál es el valor del argumento del mensaje y cuál es la variable de instancia.Buena práctica para desambiguar nombres de argumento versus nombres de variable de instancia en Objective-C

Decir que tengo un poco de clase tales como los siguientes:

@interface MyObject 
{ 
    NSString *value; 
} 
- (id)initWithValue:(NSString *)value; 
@end 

En mi aplicación Quiero que mi método init para mirar algo como esto:

- (id)initWithValue:(NSString *)value 
{ 
    self = [super init]; 
    if(self) { 
     self.value = value; // This will not work with instance variables 
    } 
} 

Sé de tres soluciones:

  1. Crear una propiedad que permite llamar self.value
  2. cambiar el nombre de variable de instancia, como _value
  3. cambiar el nombre de la variable argumento init, como initValue o argValue

no estoy satisfecho con cualquiera de estas soluciones. Agregar una propiedad hace que la propiedad esté disponible públicamente en la interfaz o, si utilizo una extensión, la oculta de los herederos. Tampoco me gusta tener diferentes nombres para las variables o usar un guión bajo, que tal vez proviene del desarrollo en otros lenguajes como Java y C#.

¿Hay alguna manera de eliminar la ambigüedad de las variables de instancia de los argumentos del mensaje? Si no, ¿hay una pauta de codificación en Cocoa para la forma de resolver este problema? Me gusta seguir las pautas de estilo cuando sea apropiado.

actualización

Después de pensar acerca de cómo hacer esto en C, se me ocurrió la solución de self->value. Esto funciona, pero produce un compilador que advierte que la declaración local de 'valor' oculta la variable de instancia. Así que esta tampoco es una solución satisfactoria ya que tengo un objetivo de advertencia cero.

Respuesta

4

Para los emisores (y por extensión inicializadores), creo que la convención es el prefijo el nombre del parámetro con new:

- (void)setCrunk:(Crunk *)newCrunk; 
- (id)initWithCrunk:(Crunk *)newCrunk; 

En general, creo que la forma más común que he visto es llamar al parámetro theCrunk, pero Apple seems to recommendaCrunk.

+0

Uso 'crunkIn' porque de lo contrario no obtendrá autocompletar. –

+0

@Josh Caswell, por coherencia es la convención de usar el prefijo que elija (nuevo, el, a) en todos los casos, incluso si no lo asigna? Tal vez simplemente se pasa a otro mensaje, como '[super setCrunk:]' –

+0

@DavidV: Diría que dejo el prefijo a menos que sea necesario desambiguar con un ivar, pero no puedo pretender que sea otra cosa que mi preferencia. –

2

Si usa solo 1, el compilador le dará una advertencia.

Se pueden combinar 1 & 2 mediante el uso de:

@synthesize value = _value; 

Si desea ocultar la variable de los herederos se puede declarar una categoría denominada vacío y declarar su propiedad allí.

Para 3 puede usar aValue para su argumento.

+1

En algún lugar (no puedo recordar) está escrito que no debe usar '_' como prefijo. Solo Apple hace eso. Debes usarlo como un sufijo, que Google recomienda en alguna parte (que tampoco recuerdo). Así que 'value = value_' ... echa un vistazo a http://www.kevincallahan.org/software/accessorizer.html y también AppCode si realmente quiere usar esta solución. –

+0

No estoy de acuerdo, es solo una convención de estilo. –

+0

¿No está de acuerdo con que Apple no recomiende usar el guión bajo como prefijo? –

3

Y cambiar el nombre a "inValue" no es una buena idea?Lo que tiene aquí, su 'solución' es compleja, especialmente con los accesorios, etc. de Obj-C 2. Como self.value y inValue son cosas diferentes, necesitan diferentes nombres.

Tenga en cuenta que puede utilizar

-(void)method1:(NSString*)value; 

en la cabecera

y

-(void)method1:(NSString*)inValue; 

en el archivo .m.

+0

He notado que puede tener diferentes nombres de argumento en la interfaz y la implementación. Mi objetivo es tener consistencia para que los desarrolladores no tengan que pensar en qué nombre se usa. ¿Has usado la convención de diferentes nombres en la interfaz y la implementación? ¿Cómo ha funcionado tu equipo? –

+0

@DavidV este es un problema que no es relevante para la interfaz, solo para la implementación. El punto de Tom es 100% válido. –

+0

@Yar, no quiero decir que el punto de Tom no sea válido. Entiendo que la interfaz seguirá siendo coherente y que un desarrollador que trabaje en la clase tendrá un esquema de nombres consistente para ivars. Es simplemente que esta es una solución que inicialmente no consideré hasta que leí la publicación de Tom y ahora lo estoy considerando. Valoro la consistencia en las interfaces más allá de la consistencia en la implementación, pero todavía me gusta tener lo último. –

Cuestiones relacionadas