2012-08-29 9 views
10

Eventuali duplicati:
How does an underscore in front of a variable in a cocoa objective-c class work?iOS: Uso di sé e underscore (_) con la variabile

Sono stato molto confuso con l'utilizzo di auto o di sottolineatura con nome di variabile dopo sintetizzarlo come sotto:

In .h file: 
@property(nonatomic, strong) NSMutableArray *users; 

In .m file: 
@synthesize users = _users; 

Sulla base delle mie comprensioni quando uso self.users, il sistema operativo farà in modo di rel facilitare la memoria allocata in precedenza nel metodo set in modo da non aver bisogno di fare attenzione in modo esplicito.

_users è una variabile di istanza per gli utenti e dovrebbe essere normalmente utilizzata durante l'accesso alla variabile utente. Se uso _users per cambiarne il valore, non licenzierà il delegato KVO che non notificherà una classe osservando il cambio di valore degli utenti.

Inoltre, self.users permette differenziando variabile dummy nel nome del metodo come qui di seguito,

- (void)assignUsers:(NSMutableArray*)users { 
     self.users = users; 
} 

Qualcuno potrebbe dirmi se c'è qualcosa che ho capito male o mancante durante l'utilizzo _users o self.users. Grazie.

+0

Ciao @qegal ho passato quella discussione e se hai letto la mia domanda, la maggior parte dei punti sono i punti di conclusione ma quello che non ho potuto ottenere è quando usare cosa! – applefreak

risposta

8

Penso che aiuti a considerare come le proprietà sono (o potrebbero essere) implementate dal compilatore.

Quando si scrive self.users = array; il compilatore traduce questo per [self setUsers:array]; Quando si scrive array = self.users; il compilatore traduce questo per array = [self users];

@synthesize aggiunge un Ivar al vostro oggetto (a meno che non si è aggiunto da soli), e implementa il -users e -setUsers: metodi di accesso per voi (a meno che non fornire il proprio)

Se stai usando ARC, -setUsers: avrà un aspetto simile:

- (void)setUsers:(NSArray *)users 
{ 
    _users = users; // ARC takes care of retaining and release the _users ivar 
} 

Se stai usando MRC (vale a dire ARC non è abilitato), -setUsers: avrà un aspetto simile *:

- (void)setUsers:(NSArray *)users 
{ 
    [users retain]; 
    [_users release]; 
    _users = users; 
} 

* - notare che questa è una versione semplificata, nonatomic attuazione -setUsers:

+0

Grazie Nick! – applefreak

+0

L'unica risposta su questo argomento che parla della differenza da una prospettiva di conteggio di riferimento con tale eleganza. Eccellente. – Ash

31

quando si utilizza il self.users, si accede alla proprietà tramite il setter o getter.

quando si utilizza lo _users, si accede direttamente alla proprietà saltando il setter o il getter.


ecco una buona dimostrazione di esso:

- (void)setUsers:(id)users { 
    self.users = users; // WRONG : it causes infinite loop (and crash), because inside the setter you are trying to reach the property via setter 
} 

e

- (void)setUsers:(id)users { 
    _users = users; // GOOD : set your property correctly 
} 

questo è il punto nel caso del getter pure.


circa la gestione di base della memoria (in caso di MRR o ARC): l'iOS dealloc l'oggetto, se non v'è più forte puntatore che mantiene in vita, non importa come si rilascia il puntatore del oggetti.

+3

caro ** Down-voters **! Sarei stato onorato di avere un riscontro sul perché le tue mani tremavano al di sopra del pulsante dell'abbonato, perché - tu credevi o no - non sono un lettore mentale per capirlo. grazie! – holex

+0

Non sono affatto sicuro di come intendevi questo: _ "Mostra un abuso di sé e ..." _, potresti elaborare per favore? la _buona dimostrazione_ mostra la __differenza__ tra l'aggirare e chiamare il setter_same_ all'interno del setter, che causa un loop ricorsivo infinito e si blocca quando lo stack è in overflow - quindi l'approccio finale evita di provocare loop infiniti in runtime. – holex

2

Sì, che è praticamente corretta. Un paio di punti minori:

iOS non rilascia automaticamente un oggetto solo perché si utilizza la notazione a punti. Rilascia un oggetto quando la proprietà è dichiarata come copy o retain (o strong in ARC). Se, ad esempio, si utilizza codice non ARC e la proprietà viene dichiarata come assign, non rilascerà l'oggetto.

Con l'ultima versione della toolchain per sviluppatori (Xcode 4.4+), non è più necessario sintetizzare manualmente le proprietà: esse vengono automaticamente sintetizzate (con il trattino di sottolineatura principale).

+0

Grazie Jim. Ho provato Xcode 4.4 con iOS 6 e sì, non richiede proprietà di sintesi, ma l'app funzionerebbe su versioni precedenti di iOS? – applefreak

+1

Sì, dalla documentazione ufficiale: [La funzione predefinita '@ synthesize' non richiede alcun SDK speciale o supporto di runtime.] (Http://developer.apple.com/library/ios/#documentation/DeveloperTools/Conceptual/WhatsNewXcode/Articles /xcode_4.html#//apple_ref/doc/uid/TP40011649-SW11) Domande del genere, dovresti leggere la documentazione. – Jim

Problemi correlati