Ciò è a che fare con l'ordine in cui i file di origine vengono compilati in Siete già probabilmente consapevoli del fatto che non si può chiamare un metodo prima che venga definita (vedi sotto pseudocodice):
var value = someMethod();
function someMethod()
{
...
}
Questo causerebbe un errore in fase di compilazione poiché someMethod() non è stato ancora definito. Lo stesso vale per le classi. Le classi sono compilate una dopo l'altra dal compilatore.
Quindi, se si immagina che tutte le classi vengano inserite in un file gigante prima della compilazione, è possibile visualizzare il problema. Guardiamo la classe Ship
e BoatYard
:
@interface BoatYard : NSObject
@property (nonatomic, retain) Ship* currentShip;
@end
@interface Ship : NSObject
@property (nonatomic, retain) NSString* name;
@property (nonatomic, assign) float weight;
@end
Ancora una volta, perché la classe Ship
non è stato ancora definito, non possiamo fare riferimento ad esso ancora. Risolvere questo particolare problema è piuttosto semplice; cambia l'ordine di compilazione e compila. Sono sicuro che sei familliar con questa schermata in XCode:
Ma siete consapevoli che è possibile trascinare i file su e giù nella lista? Ciò cambia l'ordine in cui i file verranno compilati. Pertanto, sposta semplicemente la classe Ship
sopra la classe BoatYard
e tutto è buono.
Ma, cosa succede se non si vuole farlo, o, soprattutto, cosa succede se c'è una relazione circolare tra i due oggetti? Aumentiamo la complessità di quel diagramma di oggetto con l'aggiunta di un riferimento alla corrente BoatYard
che il Ship
è in:
@interface BoatYard : NSObject
@property (nonatomic, retain) Ship* currentShip;
@end
@interface Ship : NSObject
@property (nonatomic, retain) BoatYard* currentBoatYard;
@property (nonatomic, retain) NSString* name;
@property (nonatomic, assign) float weight;
@end
Oh cara, ora abbiamo un problema. Questi due non possono essere compilati fianco a fianco. Abbiamo bisogno di un modo per informare il compilatore che la classe Ship * esiste realmente. Ed è per questo che la parola chiave @class
è così a portata di mano.
Per dirla in parole povere, stai dicendo: "Fidati di me, lo Ship
esiste davvero e lo vedrai molto presto". Per mettere tutto insieme:
@class Ship;
@interface BoatYard : NSObject
@property (nonatomic, retain) Ship* currentShip;
@end
@interface Ship : NSObject
@property (nonatomic, retain) BoatYard* currentBoatYard;
@property (nonatomic, retain) NSString* name;
@property (nonatomic, assign) float weight;
@end
Ora il compilatore sa come si compila BoatYard
, che apparirà presto una definizione Ship
di classe. Ovviamente, se così non fosse, la compilazione riuscirà comunque.
Tutta la parola chiave @class
tuttavia informa il compilatore che la classe arriverà presto. È non un sostituto per #import
.È comunque necessario importare il file di intestazione, altrimenti non sarà possibile accedere ad uno qualsiasi degli interni di classe:
@class Ship
-(void) example
{
Ship* newShip = [[Ship alloc] init];
}
Questo non può funzionare, e non riuscirà con un messaggio di errore dicendo che la nave è una dichiarazione in avanti. Una volta che hai #import "Ship.h"
, allora sarai in grado di creare l'istanza dell'oggetto.
sembra andare bene .. puoi pubblicare una parte del tuo codice? – Devarshi
anche ... è una parte ANObject di qualche altro framework? – Devarshi
Modifica la tua domanda per includere sia il contenuto di ANObject.h che l'intestazione che ti dà il problema. E per favore mostra il tuo codice attuale, non il codice inventato che potrebbe non includere il problema. –