Pregunta

Siendo nuevo en Objective-C (pero programador de C/++ desde hace mucho tiempo), estoy buscando consejos/recomendaciones sobre convenciones de nomenclatura para variables.

Mi preferencia personal sería utilizar un prefijo, por ejemplo, variables, tanto para mayor claridad dentro de las funciones como para evitar sombras en los parámetros de las funciones.Sin embargo, soy fanático de las propiedades que descartan los prefijos (a menos que también coloque un prefijo en los nombres de sus propiedades, lo cual no funciona muy bien y parece una tontería).De manera similar, podría usar la convención "self.variable", pero solo si hago de TODO una propiedad.

Entonces, dado el código a continuación, ¿cuál es su estilo de nomenclatura preferido, por ejemplo/variables de función?Y si no se molesta, ¿cómo se ocupa del sombreado de los parámetros de función?

@interface GridItem : NSObject
{
    CGRect _rect;
    ...  
}
@end

-(void) initFromRect:(CGRect)rect
{
    _rect = rect;
    ...
}

¡Salud!

¿Fue útil?

Solución

La mayoría de los proyectos de Cocoa utilizan la barra inferior como noIBOutlet prefijo de variable de instancia y no utilizar ningún prefijo para IBOutlet variables de instancia.

La razón por la que no uso barras inferiores IBOutlet Las variables de instancia son que cuando se carga un archivo nib, si tiene un método de establecimiento para una salida conectada, se llamará a ese establecimiento. Sin embargo este mecanismo hace no utilice codificación de valores clave, por lo que un IBOutlet cuyo nombre tenga el prefijo una barra inferior (p.ej. _myField) voluntad no establecerse a menos que el definidor tenga el mismo nombre que la salida (p.ej. set_myField:), que es atípico y bruto.

Además, tenga en cuenta que el uso de propiedades como self.myProp es no lo mismo que acceder a variables de instancia.Eres enviando un mensaje cuando usas una propiedad, al igual que si usaras notación entre corchetes como [self myProp].Lo único que hacen las propiedades es brindarle una sintaxis concisa para especificar tanto el captador como el definidor en una sola línea, y permitirle sintetizar su implementación;en realidad no provocan un cortocircuito en el mecanismo de envío de mensajes.Si desea acceder a una variable de instancia directamente pero anteponiendole self necesitas tratar self como un puntero, como self->myProp que realmente es un acceso al campo estilo C.

Por último, nunca utilice la notación húngara al escribir código Cocoa y evite otros prefijos como "f" y "m_", ya que marcarán el código como escrito por alguien que no lo "entiende" y provocará que ser visto con sospecha por otros desarrolladores de Cocoa.

En general, siga los consejos del Directrices de codificación para el cacao documento en el Conexión de desarrollador de Apple, y otros desarrolladores podrán recoger y comprender su código, y su código funcionará bien con todas las funciones de Cocoa que utilizan la introspección en tiempo de ejecución.

Así es como se vería una clase de controlador de ventana, usando mis convenciones:

// EmployeeWindowController.h
#import <AppKit/NSWindowController.h>

@interface EmployeeWindowController : NSWindowController {
@private
    // model object this window is presenting
    Employee *_employee;

    // outlets connected to views in the window
    IBOutlet NSTextField *nameField;
    IBOutlet NSTextField *titleField;
}

- (id)initWithEmployee:(Employee *)employee;

@property(readwrite, retain) Employee *employee;

@end

// EmployeeWindowController.m
#import "EmployeeWindowController.h"

@implementation EmployeeWindowController

@synthesize employee = _employee;

- (id)initWithEmployee:(Employee *)employee {
    if (self = [super initWithWindowNibName:@"Employee"]) {
        _employee = [employee retain];
    }
    return self;
}

- (void)dealloc {
    [_employee release];

    [super dealloc];
}

- (void)windowDidLoad {
    // populates the window's controls, not necessary if using bindings
    [nameField setStringValue:self.employee.name];
    [titleField setStringValue:self.employee.title];
}

@end

Verás que estoy usando la variable de instancia que hace referencia a un Employee directamente en mi -init y -dealloc método, mientras uso la propiedad en otros métodos.Generalmente es un buen patrón con propiedades:Solo toque la variable de instancia subyacente de una propiedad en los inicializadores, en -dealloc, y en el captador y definidor de la propiedad.

Otros consejos

Sigo el consejo de Chris Hanson con respecto al prefijo ivar de guión bajo, aunque admito que también uso guiones bajos para IBOutlets.Sin embargo, recientemente comencé a mover mi IBOutlet declaraciones a la @property línea, según La sugerencia de @mmalc.El beneficio es que todos mis ivars ahora tienen un guión bajo y se llaman los configuradores KVC estándar (es decir, setNameField:).Además, los nombres de los puntos de venta no tienen guiones bajos en Interface Builder.

@interface EmployeeWindowController : NSWindowController {
@private
    // model object this window is presenting
    Employee *_employee;

    // outlets connected to views in the window
    NSTextField *_nameField;
    NSTextField *_titleField;
}

- (id)initWithEmployee:(Employee *)employee;

@property(readwrite, retain) Employee *employee;
@property(nonatomic, retain) IBOutlet NSTextField *nameField;
@property(nonatomic, retain) IBOutlet NSTextField *titleField;

@end

Puede usar el prefijo de la barra inferior en sus ivars y aún usar el nombre que no está debajo de la barra para sus propiedades.Para descriptores de acceso sintetizados, simplemente haga esto:

@synthesize foo = _foo;

Esto le dice al compilador que sintetice la propiedad foo usando the_foo ivar.

Si escribe sus propios descriptores de acceso, simplemente use el ivar de la barra inferior en su implementación y mantenga el nombre del método que no esté bajo la barra.

Personalmente, sigo las convenciones de nomenclatura de Cocoa, usando camel-casing para funciones y variables, y camel-casing en mayúsculas para nombres de objetos (sin el NS inicial, por supuesto).

Creo que el prefijo de tipo hace que el código sea más opaco para cualquiera que no lo haya escrito (ya que todos usan invariablemente prefijos diferentes), y en un IDE moderno no es tan difícil determinar el tipo de algo.

Con la introducción de propiedades, no veo la necesidad de anteponer "_" a las variables de instancia de clase.Puede establecer una regla simple (descrita en su archivo de encabezado) según la cual se debe acceder a cualquier variable externa a la clase a través de la propiedad o mediante el uso de métodos personalizados en la clase para afectar los valores.Esto me parece mucho más limpio que tener nombres con "_" pegados al frente.También encapsula adecuadamente los valores para que pueda controlar cómo se cambian.

No me gusta usar guiones bajos como prefijos para ningún identificador, porque C y C++ reservan ciertos prefijos de guiones bajos para que los use la implementación.

Creo que usar "self.variable" es feo.

En general, utilizo identificadores simples (es decir, sin prefijos ni sufijos), por ejemplo, variables.Si tu clase es tan complicada que no puedes recordar las variables de instancia, estás en problemas.Entonces, para su ejemplo, usaría "rect" como nombre de la variable de instancia y "newRect" o "aRect" como nombre del parámetro.

Andrés:En realidad, hay muchos desarrolladores de Cocoa que no utilizan ningún prefijo de variable de instancia.También es extremadamente común en el mundo de Smalltalk (de hecho, yo diría que es casi inaudito en Smalltalk usar prefijos en variables de instancia).

Los prefijos en las variables de instancia siempre me han parecido una característica de C++ que se trasladó a Java y luego a C#.Dado que el mundo Objective-C era en gran medida paralelo al mundo C++, mientras que los mundos Java y C# son sus sucesores, eso explicaría la diferencia "cultural" que podría ver en esto entre los diferentes grupos de desarrolladores.

Mi estilo es híbrido y realmente un vestigio de los días de PowerPlant:

Los prefijos más útiles que uso son "in" y "out" para los parámetros de función/método.Esto le ayuda a saber para qué sirven los parámetros de un vistazo y realmente ayuda a prevenir conflictos entre los parámetros del método y las variables de instancia (¿cuántas veces ha visto el parámetro "tabla" en conflicto con una variable de instancia del mismo nombre)?P.ej.:

- (void)doSomethingWith:(id)inSomeObject error:(NSError **)outError;

Luego uso el nombre simple, por ejemplo, variables y nombres de propiedades:

Luego uso "the" como prefijo para variables locales:la tabla, la URL, etc.Nuevamente, esto ayuda a diferenciar entre variables locales y de instancia.

Luego, siguiendo el estilo de PowerPlant, uso algunos otros prefijos:k para constantes, E para enumeraciones, g para globales y s para estáticas.

He estado usando este estilo durante unos 12 años.

Si bien me encanta usar el prefijo de guión bajo para ivars, detesto escribir @synthesize líneas debido a toda la duplicación (no es muy SECO).Creé una macro para ayudar a hacer esto y reducir la duplicación de código.Así, en lugar de:

@synthesize employee = _employee;

Escribo esto:

ddsynthesize(employee);

Es una macro simple que utiliza el pegado de tokens para agregar un guión bajo en el lado derecho:

#define ddsynthesize(_X_) @synthesize _X_ = _##_X_

El único inconveniente es que confundirá la herramienta de refactorización de Xcode y no se le cambiará el nombre si cambia el nombre de la propiedad mediante la refactorización.

Además de lo que se ha dicho aquí, asegúrese de leer la documentación de Cocoa sobre la denominación compatible con Key Value Observing.Seguir estrictamente este patrón le será de gran ayuda a largo plazo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top