2010-07-16 33 views
136

Ho visto il seguente pezzo di codice:Che cosa fa esattamente @synthesize?

//example.h 
MKMapView * mapView1; 
@property (nonatomic, retain) MKMapView * mapView; 

//example.m 
@synthesize mapView = mapView1 

Domanda: Quale relazione tra MapView e mapView1 è? Crea set e ottenere metodo per mapView1?

Grazie!

+1

Aggiornamento: ma con l'ultimo set di strumenti @synthesize è ora (quasi) mai necessario. Vedi la risposta a [Other Overflow Question Question] (http://stackoverflow.com/questions/17019798/about-naming-the-instance-variable-in-objective-c/17019883#17019883). –

risposta

29

@synthesize crea un getter e un setter per la variabile.

Ciò consente di specificare alcuni attributi per le variabili e quando si usa la variabile @synthesize per generare la variabile getter e setter per la variabile.

Il nome della proprietà può essere uguale al nome della variabile. A volte le persone vogliono che sia diverso in modo da utilizzarlo in init o dealloc o quando il parametro viene passato con lo stesso nome della variabile.

16

Da the documentation:

si utilizza la parola chiave @synthesize per dire al compilatore che dovrebbe sintetizzare il setter e/o metodi getter per la proprietà, se non vengono fornite all'interno del blocco @implementation.

2

Vedi the apple docs

Fondamentalmente la sintetizzare crea un setMapView e MapView metodi che impostare e ottenere mapView1

2

Crea getter e setter per l'oggetto. È possibile accedere con qualcosa di simile:

MKMapView* m = object.mapView; 

o

object.mapView = someMapViewObject 

mapView1 è il nome del Ivar nella classe, MapView è il nome per il metodo getter/setter (s).

199

Nel tuo esempio, mapView1 è un un'istanza variabile (ivar), un pezzo di memoria che appartiene a un'istanza della classe definita in example.h e example.m. mapView è il nome di una proprietà . Le proprietà sono attributi di un oggetto che può essere letto o impostato utilizzando la notazione a punti: myObject.mapView. Una proprietà non ha basata su un ivar, ma la maggior parte delle proprietà lo sono. La dichiarazione @property dice semplicemente al mondo che esiste una proprietà chiamata mapView.

@synthesize mapView = mapView1;

Questa linea dice al compilatore di creare un setter e getter per mapView, e che dovrebbero utilizzare l'Ivar chiamato mapView1. Senza la parte = mapView1, il compilatore presuppone che la proprietà e ivar abbiano lo stesso nome.(In questo caso, che produrrebbe un errore di compilazione, dal momento che non v'è alcuna Ivar chiamato mapView.)

Il risultato di questo @synthesize affermazione è simile a se avessi aggiunto questo codice da soli:

-(MKMapView *)mapView 
{ 
    return mapView1; 
} 

-(void)setMapView:(MKMapView *)newMapView 
{ 
    if (newMapView != mapView1) 
    { 
    [mapView1 release]; 
    mapView1 = [newMapView retain]; 
    } 
} 

Se fate aggiungere che codice alla classe da soli, è possibile sostituire l'istruzione @synthesize con

@dynamic mapView;

la cosa principale è quello di avere una molto chiara concettuale distinzione tra ivar e proprietà. Sono davvero due concetti molto diversi.

+6

spiegazione eccellente! – ennuikiller

+1

+1 per una risposta più forte. –

+0

risposta ben spiegata, grazie! –

5

Come da documentazione Apple @Synthesize viene utilizzato solo per rinominare le variabili di istanza. Per esempio

@property NSString *str; 

@synthesize str = str2; 

Ora nella classe non è possibile utilizzare _str come la linea di cui sopra ha rinomina la variabile di istanza per str2

@property consente agli oggetti di essere utilizzati da oggetti in altre classi, o in altre parole fa l'oggetto pubblico.

+3

Apparentemente, a partire da Xcode 4.4, Clang fornisce supporto per l'autosintesi delle proprietà dichiarate. Quindi @synthesize non è più necessario nella maggior parte dei casi. Vedi http://useyourloaf.com/blog/2012/08/01/property-synthesis-with-xcode-4-dot-4.html – huyz

7

Come mi sono imbattuto in questo problema durante la modifica del codice legacy voglio rendere note aggiuntive alle risposte esistenti di cui è necessario essere a conoscenza.

Anche con una nuova versione del compilatore a volte fa la differenza se si omette @synthesize propertyName o no.

Nel caso in cui si dichiara un'istanza variabile senza sottolineatura mentre ancora sintetizzarlo, come ad esempio:

Intestazione:

@interface SomeClass : NSObject { 
    int someInt; 
} 
@property int someInt; 
@end 

Implementazione:

@implementation SomeClass 
@synthesize someInt; 
@end 

self.someInt sarà accedere alla stessa variabile di someInt. Non usare un trattino di sottolineatura principale per ivars non segue le convenzioni sui nomi, ma sono appena entrato in una situazione in cui ho dovuto leggere e modificare tale codice.

Ma se si pensa ora "Ehi, @synthesize non è importante più come si usa un compilatore più recente" vi sbagliate! La classe mostrerà quindi due ivars, ovvero someInt più una variabile _someInt generata automaticamente. Pertanto, self.someInt e someInt non indirizzeranno più le stesse variabili. Se non ti aspetti un comportamento del genere, potresti farti venire il mal di testa.

+0

"synchronize"! = "Sintetizza"? – jameshfisher

+0

Sì, questi sono 2 concetti diversi. '@ synchronize' è una direttiva per come sincronizzare i thread quando si accede alla proprietà e' @ synthesize' serve per legare la proprietà a una variabile di istanza tramite getter e setter. Il commento di –

+1

jameshfisher intendeva avvisarti che hai confuso sincronizzare e sintetizzare nella tua risposta. Tu usi i due in modo intercambiabile. – Maple

Problemi correlati