2012-05-03 18 views

risposta

71

Getter è un metodo che viene chiamato ogni volta che si accede (lettura valore da) a una proprietà (dichiarata con @property). Qualunque cosa questo metodo restituisce è considerata valore della proprietà:

@property int someNumber; 

...

- (int)someNumber { 
    return 42; 
} 

...

NSLog("value = %d", anObject.someNumber); // prints "value = 42" 

Setter è un metodo che viene richiamato ogni volta che viene modificato il valore della proprietà.

- (void)setSomeNumber: (int)newValue { // By naming convention, setter for `someValue` should 
            // be called `setSomeValue`. This is important! 
    NSLog("someValue has been assigned a new value: %d", newValue); 
} 

...

anObject.someNumber = 19; // prints "someValue has been assigned a new value: 19" 

Di solito non ha molto senso per tornare solo lo stesso valore di getter e stampare nuovo valore nel setter. Per memorizzare in realtà qualcosa si deve dichiarare una variabile di istanza (Ivar) nella classe:

@interface SomeClass : NSObject { 
    int _someNumber; 
} 

e rendere di accesso (il nome collettivo di getter e setter) per memorizzare/recuperare il suo valore:

- (int)someNumber { 
    return _someNumber; 
} 

- (void)setSomeNumber:(int)newValue { 
    _someNumber = newValue; 
} 

...

SomeClass *anObject = [[SomeClass alloc]init]; 
anObject.someNumber = 15; 
NSLog(@"It's %d", anObject.someNumber); // prints "It's 15" 

Okay, ora che la proprietà si comporta proprio come la variabile al solito. Qual è il punto nello scrivere tutto quel codice?

Innanzitutto, da ora in poi è possibile aggiungere un codice aggiuntivo agli accessor, che verrà eseguito ogni volta che si accede o si modifica la proprietà. Ci sono molte ragioni per farlo, per esempio potrei voler fare qualche tipo di calcoli nascosti, o aggiornare lo stato del mio oggetto, la cache ecc.

In secondo luogo, ci sono meccanismi interessanti chiamati Key-Value Coding (KVC) e Key-Value Observing (KVO) in cacao. Dipendono dalle proprietà. Puoi leggere informazioni su di loro nella Developer Library: KVC Programming Guide e KVO Programming Guide. Questi sono argomenti avanzati però.

Infine, nell'obiettivo C non esiste un'assegnazione statica per gli oggetti. Tutti gli oggetti sono allocati dinamicamente (reason). Se si desidera mantenere i puntatori oggetto nelle variabili di istanza (anziché nelle proprietà), sarà necessario eseguire manualmente tutta la gestione della memoria ogni volta che si assegna un nuovo valore a ivar (non vero quando è attivo). Usando le proprietà potresti mettere un po 'di codice di gestione della memoria nelle funzioni di accesso e semplificarti la vita.

Non credo che questa spiegazione abbia molto senso per qualcuno che non ha familiarità con la gestione della memoria dell'obiettivo C, quindi, o leggere alcuni documenti/tutorial reali su di esso, o semplicemente utilizzare le proprietà (invece delle variabili di istanza) fino a quando impari tutti i dettagli in un modo o nell'altro. Personalmente, non mi piace la seconda opzione, ma dipende da te.

È possibile utilizzare @synthesize per consentire al compilatore di generare automaticamente accessorie di base e variabili di istanza sottostanti. Invece del codice di cui sopra (e -(int)someNumber-(void)setSomeNumber:) si può solo scrivere

@synthesize someNumber = _someNumber; // = _someNumbers tells compiler 
             // to name the instance variable `_someNumber`. 
             // You could replace it with = `_somethingElse`, of 
             // course, but that's an ill idea. 

Questa singola linea genera int _someNumber variabile, someNumber getter e setter setSomeNumber per voi. Se vuoi che gli accessor facciano qualcosa di più complesso del semplice salvataggio/recupero del valore da qualche variabile di istanza, dovrai scriverli tu stesso.

Spero che tutto ciò abbia un senso.

3

Le proprietà "getter" e "setter" nella maggior parte dei linguaggi orientati agli oggetti forniscono un'interfaccia "esterna" o utente sui membri privati ​​delle istanze delle classi. Alcuni critici di OO si riferiranno a loro come "zucchero sintattico", ma ciò che si riduce è che i consumatori delle tue classi useranno queste interfacce che il controllo di te al livello di programmazione invece di accedere ai membri privati ​​effettivi. In questo modo, è possibile (ad esempio) proteggere una variabile privata dal ricevere un valore non valido o fuori intervallo o rendere una proprietà di sola lettura fornendo solo un getter ma nessun setter. Ancora più interessante è l'idea che i getter ei setter possano racchiudere le proprietà che non sono conservate in modo nativo nella classe, ma potrebbero (ad esempio) essere calcolate in base ad altri membri di istanza.

Getter e setter non sono sicuramente unici per l'obiettivo-C; se continui a programmare in altri linguaggi OO, ne troverai i sapori in C#, Java e altri.

Buona fortuna.

4

"Getter" e "setter" vengono utilizzati per controllare le modifiche a una variabile (campo).

Un "setter", è più spesso utilizzato nella programmazione orientata agli oggetti, in linea con il principio di incapsulamento. In base a questo principio, le variabili membro di una classe vengono rese private per nasconderle e proteggerle da altri codici, e possono essere modificate solo da una funzione membro pubblica, che prende come nuovo parametro il nuovo valore desiderato, eventualmente lo convalida e modifica il valore variabile membro privato.

Spesso un "setter" è accompagnato da un "getter" (noto anche come accessor), che restituisce il valore della variabile membro privata.

I metodi Getter/Setter possono anche essere utilizzati in ambienti non orientati agli oggetti. In questo caso, un riferimento alla variabile da modificare viene passato al metodo, insieme al nuovo valore. In questo scenario, il compilatore non può limitare il codice dall'escludere i metodi getter/setter e modificare direttamente la variabile. L'onere ricade sugli sviluppatori per garantire che la variabile venga modificata solo attraverso questi metodi e non modificata direttamente.

Nei linguaggi di programmazione che li supportano, le proprietà offrono un'alternativa conveniente senza rinunciare all'utilità dell'incapsulamento.