2011-01-19 19 views
7

Sono abituato a creare proprietà per praticamente tutto. Probabilmente troppo, dato. Uso anche variabili di istanza, ma non le riferimento a self->myvar ma piuttosto solo a myvar.Uso di -> in Cocoa

Recentemente sono stato esposto a un codice utilizzando molto self-> dove avrei utilizzato una proprietà. Quando ho detto che uno dei motivi per cui utilizzo @property (retain) è perché non voglio dover mantenere esplicitamente il mio oggetto, mi è stato detto che sono "pigro". Probabilmente è vero, ma è anche quello che voglio evitare bug in cui avrei dimenticato di mantenere.

In ogni caso, in generale, cosa ne pensate di -> nel codice Cocoa?

+4

"Di recente ho è stato esposto a un codice utilizzando un sacco di 'auto->'. .. Girati ... scappare !!!! –

risposta

6

La pigrizia è una virtù.

Io uso -> in copyWithZone:, per accedere variabili di istanza della copia. (Non utilizzo gli accessor di proprietà qui per gli stessi motivi per cui non li uso in init o dealloc - potrebbero causare effetti indesiderati che potrebbero risultare negativi nella copia semianalizzata). Io uso anche self-> in questo contesto perché come il modo in cui si legge:

other->foo = [self->foo copy]; 
other->bar = [self->bar copy]; 
other->baz = self->baz; //Non-object or object not owned (may be omitted entirely in the latter case) 

non riesco a pensare ad un altro contesto in cui io uso -> sugli oggetti.

1

IMO non c'è molto valore nell'uso -> sopra l'accesso semplice di ivar. A volte è utile per scopi di debug se vuoi accedere a un ivar di un oggetto diverso. Se si tratta solo di differenziare gli ivar dai vars locali, è possibile utilizzare uno degli schemi di denominazione stabiliti (non entrare nei dettagli qui) altrettanto bene.

L'uso delle proprietà è una storia completamente diversa. IMO nella maggior parte dei casi si dovrebbe preferire l'utilizzo di proprietà rispetto ai semplici ivar. Il mantenimento automatico è una delle ragioni, una buona astrazione un'altra.

1

Per la maggior parte delle operazioni, non utilizzare -> a meno che non si stia scrivendo codice C o C++ con Objective-C. È più semplice per te, il compilatore e la gestione della memoria se crei le proprietà e le fai riferimento in modo appropriato.

@interface MYObject : NSObject { 
@public // don't use this, please! 
    MYOtherObject *obj; 
} 

@property (retain) MYOtherObject *obj; 

@end 

@implementation MYObject 

@synthesize obj; 

@end 


// later in your code 

MYObject *thing = [[MYObject alloc] init]; 
MYOtherObject *other; 

// Good 
other = [thing obj]; 
other = thing.obj; 
other = [thing valueForKey:@"obj"]; // I hope my KVC is correct here. :(

// Bad, and soon to be deprecated I believe. (all members are @protected unless you use @public) 
other = thing->obj; 

Perché è brutto? È possibile dichiarare i membri nel file di implementazione in questo modo: (a 64 bit e iPhone)

@interface MYObject : NSObject 

@property (retain) MYOtherObject *obj; 

@end 

@implementation MYObject 

@synthesize obj = _obj; 

@end 

Qui, chiamando thing->obj produrrà nulla, ma gli errori dal momento che il membro è allocata dinamicamente a runtime.

Inoltre, come sottolinea utente @Peter Hosey, è possibile utilizzare come ->Friend C++ s 'in metodi come copyWithZone tuttavia, se non si sta facendo cose del genere, quindi stare lontano!


[EDIT]

Inoltre, se si sta cercando di spremere le prestazioni fuori l'oggetto e si sapere quello che stai facendo con quel oggetto o membro allora si potrebbe utilizzare -> per saltare il overhead del metodo di ricerca. Anche in questo caso, tuttavia, è possibile che si desideri codificare tali sezioni in C o C++ se le prestazioni sono pari a .

Oh, inoltre, non credo che l'uso di -> sia thread-safe. Se il tuo getter/setter usa @synchronize usando ->, ignorerai le protezioni.

+0

In realtà, credo che tutte le variabili di istanza (membri) sono '@ protected' di default, piuttosto che' @ private'. – NSGod

+0

@NSGod, questo è vero. io modificare che. –

+0

Si scopre il codice che vedo con questo molto è sempre esclusivamente con auto> myvar. so come cosa-> var sarebbe "cattivo", ma ancora una volta, qui stiamo parlando solo di se stessi> myvar, che AFAIK è un modo più "descrittivo" di chiamare "myvar". Penso che un'opzione "più bella" per differenziare ivar s sarebbe quella di utilizzare "_myvar" per ex, ma non sono mai stato veramente sicuro come Apple significava questo "non deve essere utilizzato da noi";.) –

1

self->variable è ridondante, dal momento che si otterrà lo stesso effetto che si riferisce al ivar da solo. In generale, l'operatore -> è utile quando la cosa si desidera accedere è un Ivar in un'altra esempio, ad esempio:

@implementation MyClass 

- (void) beLikeThisOtherThing:(MyClass *) foo 
{ 
someVariable = foo->someVariable; 
} 

@end