Domanda

Sto cercando di capire lo scopo della direttiva synthesize con il nome di proprietà prevalente. Dire che ho un'interfaccia definita come segue:

@interface Dummy ... {
    UILabel *_dummyLabel;
}

@property (retain, nonatomic) UILabel *dummyLabel;

E nel file di implementazione, ho:

@synthesize dummyLabel = _dummyLabel;

Da quello che ho capito, "dummyLabel" è solo un alias della variabile di istanza "_dummyLabel". C'è qualche differenza tra self._dummyLabel e self.dummyLabel?

È stato utile?

Soluzione

Sì. self._dummyLabel non è definito, ma non è _dummyLabel.

sintassi Dot si espande fuori per semplici chiamate di metodo, quindi non è specifico per le proprietà. Se si dispone di un metodo chiamato -(id)someObject, ad esempio nel caso di object.someObject, sarà come se hai scritto [object someObject];.

self.dummyLabel  //works
self._dummyLabel //does not work
dummyLabel       //does not work
_dummyLabel      //works
[self dummyLabel];  //works
[self _dummyLabel]; //does not work

Altri suggerimenti

La vostra comprensione è corretta. dummyLabel è il nome della proprietà, ed è non un alias per la variabile di istanza - la variabile di istanza è solo chiamato _dummyLabel. Così vale quanto segue per un'istanza di Dummy chiamato myObject:

  • [myObject dummyLabel] funziona
  • myObject.dummyLabel funziona
  • [myObject _dummyLabel] fallisce
  • myObject._dummyLabel fallisce
  • myObject->dummyLabel fallisce
  • myObject->_dummyLabel dipende dalla visibilità del Ivar (@public, @private, @protected)
  • [myObject valueForKey: @"dummyLabel"] funziona
  • [myObject valueForKey: @"_dummyLabel"] dipende l'attuazione di +accessInstanceVariablesDirectly (vale a dire che funzionerà nel caso di default in cui i rendimenti +accessInstanceVariablesDirectly YES).
  

Il vantaggio di avere un altro nome   per l'Ivar rispetto per la proprietà è   che si può facilmente vedere nel codice   quando si accede a uno o l'   altre - Andre K

Non sono in grado di trovare un pulsante 'commento' così sto dover inserire come 'risposta'.

Volevo solo per espandere il commento di Andre - sapendo quando si utilizza le proprietà sintetizzati vs la variabile di vaniglia, si sa (soprattutto in caso di setter) quando una variabile viene mantenuta / copia / rilasciati automaticamente grazie al vostro bel setter , vs essere manipolato a mano.

Naturalmente se si sta facendo le cose per bene, probabilmente non è necessario l'aiuto di un setter di mantenere / release oggetti correttamente! Ma ci possono essere altri scenari in cui anche riferendosi ai vostri Ivars come self.ivar invece di _ivar può essere utile, ad esempio quando si utilizza setter custom / getter al posto di quelli di default sintetizzato. Forse ogni volta che si modifica una proprietà, si vuole anche per memorizzare a NSUserDefaults. Così si potrebbe avere qualche codice come questo:

@interface SOUserSettings : NSObject {

BOOL _autoLoginOn;

}

@property (nonatomic, assign) BOOL autoLoginOn;

@end

@implementation SOUserSettings

@synthesize autoLoginOn = _autoLoginOn;

- (void)setAutoLoginOn:(BOOL)newAutoLoginOnValue {

   _autoLoginOn = newAutoLoginOnValue;
   [[NSUserDefaults standardUserDefaults] setBool:_autoLoginOn forKey:@"UserPrefAutoLoginOn"];
}

@end

Nota: Questo è solo il codice illustrativo, ci potrebbe essere un torto mille cose con esso

Così ora, nel codice, se si dispone di una linea che dice _autoLoginOn = YES -. Sai che non sta per essere salvato NSUserDefaults, mentre se si utilizza self.autoLoginOn = YES si sa esattamente cosa sta per accadere

La differenza tra _autoLoginOn e self.autoLoginOn non è solo semantica.

  

Non vedo alcuna grande vantaggio di   ridenominazione _dummyLabel a dummyLabel

In alcuni objC tempi di esecuzione si dispone di un disco variabili di istanza rendendo il tempo invisibile agli utenti della classe. Per attaccarle qualche prefisso (o suffisso) sulle variabili di istanza può mettere in chiaro (o più chiaro) che non vuoi che nessuno scherzi con le variabili. Tuttavia non si vuole che gunk sulle vostre funzioni pubbliche. Ciò consente di farlo fuori.

Potrebbe anche essere utile se avete bisogno di mantenere una vecchia interfaccia con una serie di nomi, allo stesso tempo come un nuovo set di API con una nuova serie di nomi (setLastname vs. setSurname).

Old post, ma penso che la sua importante ricordare, che si consiglia di variabili di accesso tramite getter e setter (così, con la notazione del punto). Accedendo direttamente un campo (_ivar) è fortemente raccomandato solo quando l'inizializzazione di esso.

C'è qualche buon articolo di Apple: https://developer.apple.com/ biblioteca / ios / # documentazione / cacao / concettuale / ProgrammingWithObjectiveC / EncapsulatingData / EncapsulatingData.html

Ultimo paragrafo:

  

Si dovrebbe sempre accedere alle variabili di istanza direttamente dall'interno   un metodo di inizializzazione perché al momento una proprietà è impostata, la   resto dell'oggetto non può ancora essere completamente inizializzato. Anche se tu   non forniscono personalizzati metodi di accesso o di sapere di eventuali effetti collaterali da   all'interno la propria classe, un futuro sottoclasse può benissimo ignorare il   comportamento.

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