Prima di tutto, non stai dichiarando una variabile; stai dichiarando una proprietà. Una proprietà è supportata da una variabile di istanza, ma aggiunge anche dei metodi. Ecco una spiegazione dei luoghi di mettere variabili:
@interface MyClass : NSObject {
NSInteger i ;
}
@end
Questo è un posto per mettere una variabile di istanza sulla tua classe. È accessibile solo con metodi della tua classe e categorie. (Sidenote: Può essere reso accessibile dall'esterno, ma non è una pratica consigliata)
altro esempio:
@interface MyClass : NSObject
@end
@implementation MyClass {
NSInteger i ;
}
@end
Questa è anche una variabile di istanza, ma è solo raggiungibile con metodi scritte all'interno quel blocco . (Sidenote: si può accedere scavando attraverso la definizione di classe, ma che non è un raccomandato (o comune) pratica)
altro esempio:
@interface MyClass : NSObject
@property NSInteger i ;
@end
è lo stesso:
@interface MyClass : NSObject {
NSInteger _i ; // you are not allowed to access it by this variable
}
- (NSInteger) i ;
- (void) setI:(NSInteger)value ;
@end
Questa è una proprietà che le persone possono ottenere e impostare.Si utilizza tale variabile nei vostri metodi o in altri metodi come:
NSLog (@"The value is %i" , self.i) ; // if it's your instance method
NSLog (@"The value is %i" , object.i) ; // if it's object's instance method
Un altro esempio:
@interface MyClass : NSObject {
NSInteger i ;
}
@property NSInteger i ;
@end
@implementation MyClass
@synthesize i ; // Causes the property to line up with the ivar by the same name.
@end
è la stessa:
@interface MyClass : NSObject {
NSInteger i ; // you ARE allowed to use this since you defined it
}
- (NSInteger) i ;
- (void) setI:(NSInteger)value ;
@end
Qui, è possibile utilizzare il getter/metodi setter o la variabile di istanza stessa. Tuttavia, dovresti generalmente usare i metodi perché tu [implicitamente] li hai dichiarati atomici in modo da avere la sincronizzazione dei thread. Se si vuole rendere non lo fanno threading (e accelerarlo, fino a quando non avete intenzione di usarlo in un ambiente multi-threaded):
@property (nonatomic) NSInteger i ;
@property (nonatomic,readonly) NSInteger i ; // only makes a getter method
Mi consiglia di evitare questo per un mentre usi le proprietà diritte perché ti aiuterà a evitare molti errori comuni. A meno che non profili il tuo programma e determini che questa è una causa di una perdita di prestazioni, dovresti probabilmente semplicemente usare le proprietà.
Un altro esempio:
@interface MyClass : NSObject
@end
@implementation MyClass
NSInteger i ;
@end
Questo è NON una variabile di istanza. È una variabile globale che è stata scritta all'interno dello scope @implementation
.
Vedere sopra per come trasformarlo in una variabile di istanza (ovvero inserirla tra parentesi).
Una nota di più:
Dichiarare una proprietà come questa:
@interface MyClass()
@property NSInteger i ;
@end
non rende privata. Tuttavia, è nascosto in un file a cui le persone generalmente non possono accedere in modo che il compilatore non sappia che esiste una proprietà.
Altre funzioni altrove nel codice può ancora chiamare:
[yourObject i] ;
per ottenere il valore di quella proprietà - ma devono sapere che è lì prima.
Addendum per rispondere a una domanda nei commenti:
proprietà sono, per impostazione predefinita, atomico. Non segue necessariamente la definizione rigorosa di atomico (questa è una lattina di worm che ti suggerisco di non guardare in questo momento), ma ha lo stesso effetto: i thread sono garantiti per vedere un valore completo e aggiornato , indipendentemente da quando un altro thread scrive su di esso. Lo fa in genere questo quando si sintetizza i metodi getter/setter:
- (NSInteger) i {
@synchronized(self) {
return i ;
}
}
- (void) setI:(NSInteger)value {
@synchronized(self) {
i = value ;
}
}
Se invece si specifica nonatomic
, sarà sintetizzare questi:
- (NSInteger) i {
return i ;
}
- (void) setI:(NSInteger)value {
i = value ;
}
Se la vostra proprietà è atomic
, allora non si dovrebbe mai accedere direttamente a Ivar. Farlo viola la protezione del threading che hai dato all'inizio.(Sidenote: ci sono casi in cui è possibile, ma aspettare fino a quando si diventa più familiarità con filettatura/sincronizzazione prima di tentare di esso.)
Il 'NSInteger' dichiarato all'interno dell'interfaccia' @ 'è una variabile globale. È anche solo una variabile, senza alcuna trappola di una proprietà (metodi di accesso, KVC, ecc.). – Rob