Domanda

Essendo un nuovo programmatore Objective-C (ma un C/++ a lungo termine), sto cercando consigli/raccomandazioni sulle convenzioni di denominazione per le variabili.

La mia preferenza personale sarebbe quella di utilizzare un prefisso per le variabili di istanza sia per chiarezza all'interno delle funzioni sia per evitare ombreggiature dei parametri della funzione.Tuttavia sono un fan delle proprietà che escludono i prefissi (a meno che non si aggiunga anche il prefisso ai nomi delle proprietà, che non funziona troppo bene e sembra stupido).Allo stesso modo potrei usare la convenzione "self.variable", ma solo se rendo TUTTO una proprietà.

Quindi, dato il codice seguente, qual è il tuo stile di denominazione preferito per le variabili di istanza/funzione?E se non ti preoccupi, come gestisci l'ombreggiatura sui parametri delle funzioni?

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

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

Saluti!

È stato utile?

Soluzione

La maggior parte dei progetti Cocoa utilizzano underbar come non-IBOutlet prefisso della variabile di istanza e non utilizzare alcun prefisso per IBOutlet variabili di istanza.

Il motivo per cui non uso le barre inferiori IBOutlet variabili di istanza è che quando viene caricato un file pennino, se si dispone di un metodo setter per una presa collegata, verrà chiamato quel setter. Tuttavia questo meccanismo lo fa non utilizzare la codifica valore-chiave, quindi un IBOutlet il cui nome ha il prefisso underbar (per esempio. _myField) Volere non essere impostato a meno che il setter non abbia lo stesso nome della presa (per esempio. set_myField:), che è non standard e lordo.

Inoltre, tieni presente che l'utilizzo di proprietà come self.myProp È non lo stesso che accedere alle variabili di istanza.Sei inviando un messaggio quando usi una proprietà, proprio come se usassi la notazione tra parentesi come [self myProp].Tutto ciò che le proprietà fanno è fornire una sintassi concisa per specificare sia il getter che il setter in un'unica riga e consentire di sintetizzare la loro implementazione;in realtà non cortocircuitano il meccanismo di invio del messaggio.Se desideri accedere direttamente a una variabile di istanza ma prefiggila con self devi trattare self come puntatore, come self->myProp che in realtà è un accesso al campo in stile C.

Infine, non usare mai la notazione ungherese quando scrivi il codice Cocoa, ed evita altri prefissi come "f" e "m_" — che contrassegneranno il codice come se fosse stato scritto da qualcuno che non lo "capisce" e lo farà sì. essere visto con sospetto da altri sviluppatori di Cocoa.

In generale, seguire i consigli in Linee guida per la codifica del cacao documento al Connessione sviluppatore Apple, e altri sviluppatori saranno in grado di apprendere e comprendere il tuo codice e il tuo codice funzionerà bene con tutte le funzionalità di Cocoa che utilizzano l'introspezione del runtime.

Ecco come potrebbe apparire una classe controller finestra, usando le mie convenzioni:

// 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

Vedrai che sto utilizzando la variabile di istanza che fa riferimento ad an Employee direttamente nel mio -init E -dealloc metodo, mentre utilizzo la proprietà in altri metodi.Questo è generalmente un buon modello con proprietà:Tocca sempre e solo la variabile di istanza sottostante per una proprietà negli inizializzatori, in -dealloc, e nel getter e setter per la proprietà.

Altri suggerimenti

Seguo il consiglio di Chris Hanson per quanto riguarda il prefisso ivar del carattere di sottolineatura, anche se ammetto di utilizzare il carattere di sottolineatura anche per IBOutlets.Tuttavia, di recente ho iniziato a spostare il mio IBOutlet dichiarazioni al @property linea, come da Il suggerimento di @mmalc.Il vantaggio è che tutti i miei ivar ora hanno un trattino basso e vengono chiamati i setter KVC standard (ad es. setNameField:).Inoltre, i nomi delle prese non hanno caratteri di sottolineatura in 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

Puoi utilizzare il prefisso underbar sui tuoi ivar e utilizzare comunque il nome non underbar per le tue proprietà.Per gli accessori sintetizzati, basta fare questo:

@synthesize foo = _foo;

Questo dice al compilatore di sintetizzare la proprietà foo usando the_foo ivar.

Se scrivi le tue funzioni di accesso, usa semplicemente la ivar underbar nella tua implementazione e mantieni il nome del metodo non underbar.

Personalmente, seguo le convenzioni di denominazione Cocoa, utilizzando il cammello per funzioni e variabili e il maiuscolo per i nomi degli oggetti (senza la NS iniziale ovviamente).

Trovo che il prefisso del tipo renda il codice più opaco per chiunque non lo abbia scritto (poiché tutti usano invariabilmente prefissi diversi) e in un IDE moderno non è poi così difficile capire il tipo di qualcosa.

Con l'introduzione delle proprietà non vedo la necessità di anteporre "_" alle variabili di istanza della classe.È possibile impostare una regola semplice (descritta nel file di intestazione) secondo cui è necessario accedere a qualsiasi variabile esterna alla classe tramite la proprietà o utilizzando metodi personalizzati sulla classe per influenzare i valori.Questo mi sembra molto più pulito che avere nomi con "_" incollato sul davanti.Inoltre incapsula correttamente i valori in modo da poter controllare il modo in cui vengono modificati.

Non mi piace usare i caratteri di sottolineatura come prefissi per eventuali identificatori, perché C e C++ entrambi riservano determinati prefissi di sottolineatura da utilizzare da parte dell'implementazione.

Penso che usare "self.variable" sia brutto.

In generale, utilizzo identificatori semplici (ovvero senza prefissi né suffissi) per le variabili di istanza.Se la tua classe è così complicata che non riesci a ricordare le variabili di istanza, sei nei guai.Quindi, per il tuo esempio, utilizzerei "rect" come nome della variabile di istanza e "newRect" o "aRect" come nome del parametro.

Andrea:In realtà ci sono molti sviluppatori Cocoa che non utilizzano affatto i prefissi delle variabili di istanza.È anche estremamente comune nel mondo Smalltalk (in effetti, direi che è quasi inaudito in Smalltalk utilizzare prefissi sulle variabili di istanza).

I prefissi sulle variabili di istanza mi hanno sempre colpito come un linguaggio C++ che è stato portato in Java e poi in C#.Poiché il mondo Objective-C era in gran parte parallelo al mondo C++, dove i mondi Java e C# ne sono i successori, ciò spiegherebbe la differenza "culturale" che potresti vedere su questo tra i diversi gruppi di sviluppatori.

Il mio stile è ibrido e in realtà è un retaggio dei tempi di PowerPlant:

I prefissi più utili che utilizzo sono "in" e "out" per i parametri di funzione/metodo.Questo ti aiuta a sapere a colpo d'occhio a cosa servono i parametri e aiuta davvero a prevenire conflitti tra i parametri del metodo e le variabili di istanza (quante volte hai visto il parametro "tabella" in conflitto con una variabile di istanza con lo stesso nome).Per esempio.:

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

Quindi utilizzo il nome nudo per le variabili di istanza e i nomi di proprietà:

Quindi utilizzo "the" come prefisso per le variabili locali:theTable, theURL, ecc.Ancora una volta questo aiuta a distinguere tra variabili locali e di istanza.

Quindi, seguendo lo stile PowerPlant, utilizzo una manciata di altri prefissi:k per costanti, E per enumerazioni, g per globali e s per statiche.

Sto usando questo stile da qualcosa come 12 anni ormai.

Anche se adoro usare il prefisso del carattere di sottolineatura per ivars, detesto scrivere @synthesize linee a causa di tutte le duplicazioni (non è molto ASCIUTTO).Ho creato una macro per aiutare a farlo e ridurre la duplicazione del codice.Quindi, invece di:

@synthesize employee = _employee;

Scrivo questo:

ddsynthesize(employee);

È una semplice macro che utilizza l'incollaggio di token per aggiungere un carattere di sottolineatura sul lato destro:

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

L'unico svantaggio è che confonderà lo strumento di refactoring di Xcode e non verrà rinominato se si rinomina la proprietà tramite il refactoring.

Insieme a quanto detto qui, assicurati di leggere la documentazione di Cocoa sulla denominazione conforme al rispetto del valore chiave.Seguire rigorosamente questo schema ti aiuterà molto a lungo termine.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top