2010-08-19 13 views
54

Ho evitato in precedenza i caratteri di sottolineatura nei nomi delle variabili, forse un residuo dei giorni del college in Java. Quindi quando definisco una proprietà nell'obiettivo C questo è ciò che faccio naturalmente.Prefisso dei nomi delle proprietà con un trattino basso nell'obiettivo C

// In the header 
@interface Whatever 
{ 
    NSString *myStringProperty 
} 

@property (nonatomic, copy) NSString *myStringProperty; 

// In the implementation 
@synthesize myStringProperty; 

Ma in quasi tutti gli esempi è fatto come

// In the header 
@interface Whatever 
{ 
    NSString *_myStringProperty 
} 

@property (nonatomic, copy) NSString *myStringProperty; 

// In the implementation 
@synthesize myStringProperty = _myStringProperty; 

Devo superare la mia avversione per la sottolineatura perché questo è l'unico modo che dovrebbe essere fatto, c'è una buona ragione per questo lo stile è il preferito?

Aggiornamento: Con sintesi proprietà automatica al giorno d'oggi è possibile lasciare il @synthesize e il risultato è lo stesso che se avessi usato

@synthesize myStringProperty = _myStringProperty; 

che mostra chiaramente la preferenza di Apple. Da allora ho imparato a smettere di preoccuparmi e ad amare la sottolineatura.

+7

Un collegamento alla domanda originale che pensi che questo duplichi salverebbe un po 'di tempo gli utenti futuri. – user2067021

risposta

3

È puramente un problema di stile.

Non so quali esempi utilizzano lo stile sottolineato di ivar. Gli esempi ufficiali Apple (ad esempio CryptoExercise) non prefissano gli ivars con _.

+1

Apple lo utilizza per il proprio codice –

+1

@Phil: Mai visto quelli. Ma se esistono davvero ciò significa che non esiste uno standard sulla denominazione di ivars riguardo al principale '_'. – kennytm

+0

La guida allo stile Obj-C di Google adotta un approccio simile, raccomandando una sottolineatura finale per ivars: http://google-styleguide.googlecode.com/svn/trunk/objcguide.xml#Variable_Names –

47

Uso sempre caratteri di sottolineatura. Crea una chiara distinzione tra variabili locali e variabili di istanza. Evita anche avvisi del compilatore nella seguente situazione:

@interface MyClass 
{ 
    NSString *name 
} 

@property (nonatomic, copy) NSString *name; 

- (id) initWithName:(NSString *) name; 
@end 

@implementation MyClass 

@synthesize name; 

// The following method will result in a compiler warning 
// (parameter name same as ivar name) 
- (id) initWithName:(NSString *) name { 
    if (self = [super init]) { 
     self.name = name; 
    } 

    return self; 
} 

@end 

EDIT:

Dopo dover sopportare downvotes e la lettura attraverso i commenti, mi permetta di provare a fare il mio punto:

Apple consiglia quegli ivar hanno lo stesso nome della loro proprietà. Apple consiglia anche che le proprietà inizino con una lettera minuscola. E Apple raccomanda anche che le variabili locali inizino con una lettera minuscola.

Ora hai un problema, perché quando leggi un pezzo di codice e vedi una variabile in uso, non puoi dire dalla convenzione di denominazione se questa variabile è un ivar o una variabile locale. Questo fa schifo. La soluzione è avere diverse convenzioni di denominazione per ivars e variabili locali. Questo è solo un buon senso.

Il modo in cui si implementa questa convenzione di denominazione è irrilevante. Se vuoi davvero, puoi semplicemente aggiungere "_WOOHAHA" ai nomi di ivar. Non mi interessa (ma forse altri lo faranno). Il fatto è che le persone che sanno quello che stanno facendo hanno deciso di andare con il "prefisso di sottolineatura" per ivars. IMHO, hanno preso la decisione giusta, anche se la loro azienda consiglia qualcos'altro. (gli sviluppatori di cui sto parlando sono le persone che scrivono alcuni importanti framework Apple e le classi .NET Framework)

Alla fine, la qualità del codice è più importante che seguire una regola stupida che non è nemmeno seguita dal persone che lo predicano.


Un'altra osservazione circa il codice che hai mostrato: non utilizzare mai mantenere sulle proprietà di stringa. È necessario utilizzare copia invece.

Per maggiori informazioni sulla copia/conservano sulle proprietà, vedere:

NSString property: copy or retain?

+5

Non si tratta di questo. Riguarda le convenzioni di denominazione. Quando vedi il codice che usa una variabile che ha come prefisso un trattino basso, sai subito che è un ivar e non una variabile locale. Apple lo fa in questo modo e Microsoft usa questa convenzione nel completo codice di .NET framework. –

+0

Grazie per aver segnalato l'errore di conservazione/copia nel codice. – mbehan

+0

Suppongo che non si tratti di una convenzione comune, basta dare un'occhiata al codice di esempio di Apple. Se si intende che è utilizzato nel codice di Apple, non significa che sia standard per la ragione sopra. – rano

6

Apple si riserva selettori che iniziano con sottolineatura per i loro metodi "privati" e che comprenda le proprietà. Non penso però che riservino per i nomi di ivar.

Personalmente, eviterei di usare underscore per iniziare qualsiasi tipo di nome di variabile. È una convenzione opaca. Cosa succede se qualcun altro usa il carattere di sottolineatura per le persone del luogo e nessuna sottolineatura per le variabili di istanza? Cosa succede se si omette accidentalmente il carattere di sottolineatura in un metodo in cui è definito un locale con lo stesso nome?

È molto meglio rendere i nomi locali diversi dai nomi di ivar. Per esempio in un setter potresti usare newName o neWValue.

+0

Si prega di avere la cortesia di lasciare un commento se si downvote – JeremyP

+0

@ Yar: A cosa si riferisce anche come "non è più vero o non è mai stato"? – JeremyP

+0

@Yar OK, beh nel 2010, quando ho scritto il post, era vero che i nomi dei selettori riservati a Apple avevano il prefisso con il trattino basso per i loro metodi privati. In effetti, ho appena controllato e questo è ancora vero. https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingMethods.html#//apple_ref/doc/uid/20001282-1003829-BCIBDJCA – JeremyP

18

L'attuale pratica suggerita di Objective-C 2.0 è quella di utilizzare lo stesso nome di ivar come proprietà. Puoi facoltativamente assegnare un ivar diverso nella dichiarazione @property, ma il fatto che per impostazione predefinita, gli accessori sintetizzati per una proprietà accederanno a ivar con lo stesso nome della proprietà, indica che è il modello che si aspetta che tu segua.

Non importa quale sia, dal momento che gli oggetti devono ancora inviare messaggi a se stessi per accedere alle proprietà, è difficile confondere quando si è accesso a una proprietà o quando si sta accedendo direttamente il suo ivar supporto, anche se utilizzando l'accesso dot 2.0 le proprietà lo rendono più possibile. L'utilizzo della sintassi di passaggio dei messaggi standard rende l'intento più esplicito, IMO.

@interface Foo : NSObject { 
    NSNumber *bar; 
} 
@property(readwrite, retain) NSNumber * bar 
@end 

@implementation Foo 
@synthesize bar; 

-(void) baz { 
    NSNumber *numberOne = [NSNumber numberWithInt: 1]; 
    //Both set the value of bar through either the your custom or the synthesized setter method 
    [self setBar:numberOne]; 
    self.bar = numberOne; 

    //Both get the value of bar through your synthesized or your custom accessor method 
    NSNumber *fooBar = [self bar]; 
    fooBar = self.bar; 

    //Both manipulate the bar ivar directly 
    bar = numberOne; 
    fooBar = bar; 
} 
@end 
1

La parte KVC del runtime si aspetta un nome o _name ivar quando si utilizza valueForKey: su un oggetto quando non riesci a trovare un messaggio per recuperare quella variabile. vedi http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/SearchImplementation.html

Se il runtime cerca di _name e la documentazione di apple menziona prima il nome, potrebbe esserci una buona ragione per questo. Diamo un'occhiata ad alcune classi di SDK: UINavigationBar.h questa classe ha caratteri di sottolineatura davanti a tutti i ivars, anche UIView ... la lista continua. Beh, forse è così con il nuovo iOS SDK fangled e le buone classi di NS * non fanno cose così ... sbagliate; usano anche il carattere di sottolineatura nei file di intestazione.

Apple utilizza il trattino di sottolineatura nei messaggi API privati ​​e ivars. Non riesco a capire perché i loro esempi non spingano questo comportamento in particolare quando il runtime si preoccupa di avere questa cosiddetta "convenzione di denominazione" codificata nel percorso di ricerca delle variabili. Sarebbe bello vedere un po 'di coerenza.

Solo una nota, c'è uno schema di denominazione rigoroso che devi seguire per essere conforme a KVC; il link sopra ti aiuta a conformarti a questo per usare questa comoda funzionalità del runtime.

2

Mi limiterò a sottolineare che un nuovo progetto di navigazione che utilizza i dati principali utilizza caratteri di sottolineatura per impostazione predefinita e rende private le variabili.

@interface MyTestAppDelegate : NSObject <UIApplicationDelegate> { 

    UIWindow *window; 
    UINavigationController *navigationController; 

@private 
    NSManagedObjectContext *managedObjectContext_; 
    NSManagedObjectModel *managedObjectModel_; 
    NSPersistentStoreCoordinator *persistentStoreCoordinator_; 
} 

@interface RootViewController : UITableViewController <NSFetchedResultsControllerDelegate> { 

@private 
    NSFetchedResultsController *fetchedResultsController_; 
    NSManagedObjectContext *managedObjectContext_; 
} 
+0

Buone convenzioni di denominazione; sottolineatura infine per varibales privati. – user40910

29

La convenzione di denominazione per la variabile di istanza con prefisso _ è ora chiaramente indicato da Apple nel "Codifica Linee guida per Cacao", dopo la revisione del 2012-02-16, con la sua ragione.

Assicurarsi che il nome della variabile di istanza descriva concisamente l'attributo memorizzato.Di solito, non si dovrebbe accedere direttamente alle variabili di istanza, ma si dovrebbero usare metodi accessor (si accede alle variabili di istanza direttamente nei metodi init e dealloc). Per aiutare a segnalare questo, i nomi delle variabili di istanza prefisso con un underscore (_), ad esempio:

@implementation MyClass { 
    BOOL _showsTitle; 
} 

Se sintetizzare la variabile di istanza utilizzando una proprietà dichiarata, specificare il nome della variabile di istanza in la dichiarazione @synthesize.

@implementation MyClass 
@synthesize showsTitle=_showsTitle; 

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingIvarsAndTypes.html#//apple_ref/doc/uid/20001284-BAJGIIJE

La conferenza in iTunes U, iPhone App per lo sviluppo CS193p Autunno 2011 tenuto da Paul Hegarty presso la Stanford University, spiega anche questa convenzione.

http://itunes.apple.com/itunes-u/ipad-iphone-application-development/id473757255

Ne sono consapevole che questa domanda viene chiesto un po 'di tempo fa, ma io stesso ho avuto la stessa domanda e ha voluto condividere i miei risultati.

Problemi correlati