2012-01-05 8 views
5

Mi imbatto in uno scenario abbastanza comune in Objective-C dove passo una variabile ad un metodo init e poi voglio assegnarlo ad una variabile di istanza del stesso nome. Tuttavia non ho trovato un modo per definire le variabili per chiarire quale sia il valore dall'argomento del messaggio e quale sia la variabile di istanza.Buone pratiche per disambiguare i nomi degli argomenti rispetto ai nomi delle variabili di istanza in Objective-C

Dire che ho un po 'di classe come il seguente:

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

Nella mia implementazione voglio che il mio metodo init a guardare qualcosa di simile:

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

So di tre soluzioni:

  1. Creare una proprietà, che consente di chiamare self.value
  2. Rinominare la mia variabile di istanza, come ad esempio _value
  3. Rinominare la mia variabile argomento init, come ad esempio initValue o argValue

Io non sono soddisfatto di una qualsiasi di queste soluzioni. L'aggiunta di una proprietà rende la proprietà pubblicamente disponibile sull'interfaccia oppure, se si utilizza un'estensione, la si nasconde dagli ereditari. Inoltre non mi piace avere nomi diversi per le variabili o usare un trattino basso, che forse deriva dallo sviluppo in altri linguaggi come Java e C#.

C'è un modo per disambiguare le variabili di istanza dagli argomenti dei messaggi? In caso contrario, c'è una linea guida di codifica in Cocoa su come risolvere questo problema? Mi piace seguire le linee guida di stile quando appropriato.

Aggiornamento

Dopo pensando a come fare questo in C, mi si avvicinò con la soluzione di self->value. Funziona, ma genera un avvertimento del compilatore che la dichiarazione locale di 'valore' nasconde la variabile di istanza. Quindi questa soluzione non è soddisfacente visto che ho un obiettivo di avvertimento zero.

risposta

4

Per setter (e inizializzatori di estensione), credo che la convenzione è quello di anteporre il nome del parametro con new:

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

In generale, penso che la forma più comune che ho visto è quello di chiamare il parametro theCrunk, ma Apple seems to recommendaCrunk.

+0

Io uso 'crunkIn' perché altrimenti non si ottiene il completamento automatico. –

+0

@Josh Caswell, per coerenza è la convenzione di utilizzare il prefisso che si sceglie (nuovo, a, a) in tutti i casi, anche se non lo si assegna? Forse è semplicemente passato in un altro messaggio, come ad esempio '[super setCrunk:]' –

+0

@DavidV: Direi di lasciare il prefisso disattivato a meno che non sia necessario disambiguare con un ivar, ma non posso fingere che sia qualcosa di diverso da la mia preferenza. –

2

Se si utilizza solo 1 il compilatore ti darà un avviso.

È possibile combinare 1 & 2 utilizzando:

@synthesize value = _value; 

Se si desidera nascondere la variabile dagli eredi si può dichiarare una categoria denominata vuoto e dichiarare la vostra proprietà lì.

Per 3 è possibile utilizzare aValore per il proprio argomento.

+1

Da qualche parte (non ricordo) è scritto che non si deve usare '_' come prefisso. Solo Apple lo fa. Dovresti usarlo come suffisso, che Google consiglia da qualche parte (che non ricordo nemmeno io). Quindi 'value = value_' ... controlla http://www.kevincallahan.org/software/accessorizer.html e anche AppCode se sei seriamente intenzionato a utilizzare questa soluzione. –

+0

Non sono d'accordo, è solo una convenzione di stile. –

+0

Non siete d'accordo sul fatto che Apple sconsiglia di usare il carattere di sottolineatura come prefisso? –

3

E cambiare il nome in "inValue" non è una buona idea?Quello che hai qui - la tua 'soluzione' è complessa, specialmente con gli accessor, ecc. Di Obj-C 2. Poiché self.value e inValue sono cose diverse, hanno bisogno di nomi diversi.

noti che è possibile utilizzare

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

nell'intestazione

e

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

nel file .m.

+0

Ho notato che è possibile avere nomi di argomenti diversi nell'interfaccia e nell'implementazione. Il mio obiettivo è di avere coerenza in modo che gli sviluppatori non debbano pensare a quale nome viene utilizzato. Hai usato la convenzione di nomi diversi nell'interfaccia e nell'implementazione? Come ha funzionato per la tua squadra? –

+0

@DavidV questo è un problema che non è rilevante per l'interfaccia, ma solo per l'implementazione. Il punto di Tom è valido al 100%. –

+0

@ Yar, non intendo dire che il punto di Tom non è valido. Comprendo che l'interfaccia rimarrà coerente e uno sviluppatore che lavora nella classe avrà uno schema di denominazione coerente per ivars. È semplicemente che questa è una soluzione che inizialmente non ho considerato fino a quando non ho letto il post di Tom e ora lo sto prendendo in considerazione. Apprezzo la coerenza delle interfacce rispetto alla coerenza nell'implementazione, ma mi piace comunque avere quest'ultimo. –

Problemi correlati