Ora che abbiamo esplorato quali tipi di dati sono disponibili, possiamo parlare di utilizzarli effettivamente in modo produttivo. Abbiamo imparato come dichiarare le proprietà in Hello, Objective-C, ma questo capitolo approfondisce le sfumature delle proprietà pubbliche e delle variabili di istanza. In primo luogo, daremo una rapida occhiata alla sintassi di base delle proprietà e delle variabili di istanza, e poi discuteremo come utilizzare gli attributi di comportamento per modificare i metodi di accesso.
Le proprietà possono essere dichiarate in un'interfaccia usando il @proprietà
direttiva. Come una rapida recensione, diamo un'occhiata al Person.h
file che abbiamo creato nel capitolo Hello, Objective-C:
#importare@interface Person: NSObject @property (copy) NSString * nome; @fine
Questo dichiara una proprietà chiamata nome
di tipo NSString
. Il (copia)
attributo dice al runtime cosa fare quando qualcuno tenta di impostare il valore di nome
. In questo caso, crea una copia indipendente del valore invece di puntare all'oggetto esistente. Ne parleremo di più nel prossimo capitolo, Gestione della memoria.
In Hello, Objective-C, abbiamo usato il @sintetizzare
direttiva per creare automaticamente metodi getter e setter. Ricorda che il metodo getter è semplicemente il nome della proprietà e il metodo setter predefinito è imposta nome
:
#import "Person.h" @implementation Person @synthesize name = _name; @fine
Ma è anche possibile creare manualmente i metodi di accesso. Fare questo manualmente aiuta a capire cosa @proprietà
e @sintetizzare
stanno facendo dietro le quinte.
Esempio di codice incluso: ManualProperty
Innanzitutto, aggiungi una nuova proprietà al Persona
interfaccia:
@property (copy) NSString * nome; @property unsigned int age;
Si noti che stiamo archiviando età
come un tipo di dati primitivi (non un puntatore a un oggetto), quindi non è necessario un asterisco prima del nome della proprietà. Di nuovo dentro Person.m
, definire esplicitamente i metodi di accesso:
- (unsigned int) age return _age; - (void) setAge: (unsigned int) age _age = age;
Questo è esattamente ciò @sintetizzare
avrebbe fatto per noi, ma ora abbiamo la possibilità di convalidare i valori prima che vengano assegnati. Tuttavia, ci manca una cosa: la _età
variabile di istanza. @sintetizzare
creato automaticamente a _nome
ivar, permettendoci di rinunciare a questo per il nome
proprietà.
Le variabili di istanza, note anche come ivars, sono variabili destinate ad essere utilizzate all'interno della classe. Possono essere dichiarati all'interno di parentesi graffe dopo il @interfaccia
o @implementazione
direttive. Ad esempio, in Person.h
, modificare la dichiarazione dell'interfaccia come segue:
@interface Person unsigned int _age;
Questo definisce una variabile di istanza chiamata _età
, quindi questa classe dovrebbe ora compilare correttamente. Per impostazione predefinita, le variabili di istanza dichiarate in un'interfaccia sono protetta. La definizione della classe C # equivalente sarebbe qualcosa di simile:
class Person protected uint _age;
I modificatori di ambito Objective-C sono gli stessi di C #: le variabili private sono accessibili solo alla classe contenitore, le variabili protette sono accessibili a tutte le sottoclassi e le variabili pubbliche sono disponibili per altri oggetti. È possibile definire l'ambito delle variabili di istanza con il @privato
, @protected
, e @pubblico
direttive all'interno di @interfaccia
, come dimostrato nel seguente codice:
@interface Person: NSObject @private NSString * _ssn; @protected int _age senza segno; @public NSString * lavoro;
Gli ivars pubblici sono in realtà un po 'al di fuori delle norme Objective-C. Una classe con variabili pubbliche si comporta più come una struttura C che come una classe; invece della consueta sintassi di messaggistica, è necessario utilizzare il ->
operatore puntatore. Per esempio:
Person * frank = [[Person alloc] init]; franco-> lavoro = @ "Astronauta"; NSLog (@ "% @", franco-> lavoro); // NOT: [franco di lavoro];
Tuttavia, nella maggior parte dei casi, ti consigliamo di nascondere i dettagli di implementazione usando un @proprietà
dichiarazione invece di variabili di istanza pubbliche. Inoltre, poiché le variabili di istanza sono dettagli di implementazione tecnica, molti programmatori amano mantenere tutti variabili di istanza private. Con questo in mente, ivar dichiarato in @implementazione
sono privati per impostazione predefinita. Quindi, se dovessi spostare il _età
dichiarazione a Person.m
invece dell'intestazione:
@implementation Person unsigned int _age;
_età
sarebbe ambito come a privato variabile. Tieni questo a mente quando lavori con le variabili di istanza nelle sottoclassi, poiché i diversi valori predefiniti per l'interfaccia rispetto alla dichiarazione di implementazione possono confondere i nuovi arrivati con Objective-C.
Ma abbastanza su variabili di istanza; torniamo alle proprietà. I metodi Accessor possono essere personalizzati utilizzando diversi attributi di dichiarazione di proprietà (ad es., (copia)
). Alcuni degli attributi più importanti sono:
getter = getterName
- Personalizza il nome del metodo accessor getter. Ricorda che il valore predefinito è semplicemente il nome della proprietà.setter = setterName
- Personalizza il nome del metodo di accesso setter. Ricorda che il valore predefinito è impostato
seguito dal nome della proprietà (ad es., imposta nome
).sola lettura
- Rendi la proprietà di sola lettura, nel senso che verrà sintetizzato solo un getter. Per impostazione predefinita, le proprietà sono di lettura-scrittura. Questo non può essere usato con setter
attributo.nonatomic
- Indica che i metodi di accesso non devono essere thread-safe. Le proprietà sono atomiche per impostazione predefinita, il che significa che Objective-C utilizzerà un lock / retain (descritto nel prossimo capitolo) per restituire completare valore da un getter / setter. Si noti, tuttavia, che questo fa non garantire l'integrità dei dati attraverso i thread, solo che getter e setter saranno atomici. Se non si è in un ambiente con thread, le proprietà non atomiche sono molto più veloci.Un caso di uso comune per la personalizzazione dei nomi getter è per le convenzioni di denominazione booleana. A molti programmatori piace anteporre è
ai nomi delle variabili booleane. Questo è facile da implementare tramite il procacciatore
attributo:
@property (getter = isEmployed) BOOL impiegato;
Internamente, la classe può usare il occupato
variabile, ma altri oggetti possono usare il isEmployed
e setEmployed
accessori per interagire con l'oggetto:
Person * frank = [[Person alloc] init]; [franco setName: @ "Frank"]; [franco schierato: SÌ]; se ([franco è implementato]) NSLog (@ "Frank è impiegato"); else NSLog (@ "Frank is unemployed");
Molti degli altri attributi di proprietà si riferiscono alla gestione della memoria, che sarà discussa nella prossima sezione. È anche possibile applicare più attributi a una singola proprietà separandoli con virgole:
@property (getter = isEmployed, readonly) BOOL impiegato;
Oltre ai metodi getter / setter, è anche possibile utilizzare la notazione dot per accedere alle proprietà dichiarate. Per gli sviluppatori C #, questo dovrebbe essere molto più familiare della sintassi di messaggistica quadrata di Objective-C:
Person * frank = [[Person alloc] init]; frank.name = @ "Frank"; // Uguale a [franco setName: @ "Frank"]; NSLog (@ "% @", franco.name); // Come [nome franco];
Si noti che questo è solo un vantaggio: si traduce direttamente nei metodi getter / setter descritti in precedenza. Notazione a punti non può essere usato per esempio metodi.
Le proprietà sono un aspetto integrale di qualsiasi linguaggio di programmazione orientato agli oggetti. Sono i dati su cui operano i metodi. Il @proprietà
direttiva è un modo conveniente per configurare il comportamento di una proprietà, ma non fa nulla che non possa essere fatto creando manualmente metodi getter e setter.
Nel prossimo capitolo, esamineremo in dettaglio come vengono memorizzate le proprietà nella memoria, nonché alcuni nuovi attributi di proprietà per il controllo di questo comportamento. Dopodiché, approfondiremo i metodi, che completano gli strumenti core-oriented di Objective-C.
Questa lezione rappresenta un capitolo di Objective-C, un eBook gratuito del team di Syncfusion.