C'est de l'ordre de la source, les fichiers sont compilés dans. Vous êtes probablement déjà au courant que vous ne pouvez pas appeler une méthode avant de elle est définie (voir ci-dessous le pseudo-code):
var value = someMethod();
function someMethod()
{
...
}
Ce serait la cause d'une erreur de compilation car someMethod() n'a pas encore été défini. La même chose est vraie de classes. Les Classes sont compilés les uns après les autres par le compilateur.
Donc, si vous imaginez toutes les classes de la mettre dans un géant de fichier avant la compilation, vous pourriez être en mesure de voir le problème. Regardons l' Ship
et BoatYard
classe:
@interface BoatYard : NSObject
@property (nonatomic, retain) Ship* currentShip;
@end
@interface Ship : NSObject
@property (nonatomic, retain) NSString* name;
@property (nonatomic, assign) float weight;
@end
Une fois de plus, parce que l' Ship
de la classe n'a pas encore été défini, nous ne pouvons pas nous référer encore. La résolution de ce problème particulier est assez simple; changer l'ordre de compilation et de les compiler. Je suis sûr que vous êtes familliar avec cet écran dans XCode:
Mais êtes-vous conscient que vous pouvez faire glisser les fichiers vers le haut et vers le bas dans la liste? Cela change l'ordre dans lequel les fichiers seront compilés dans. Par conséquent, il suffit de déplacer l' Ship
classe au-dessus de l' BoatYard
classe, et tout est bon.
Mais, si vous ne voulez pas le faire, ou plus important encore, que si il y a une circulaire de la relation entre les deux objets? Nous allons augmenter la complexité du diagramme d'objets par l'ajout d'une référence à l'actuel BoatYard
que l' Ship
est en:
@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, maintenant nous avons un problème. Ces deux ne peuvent pas être compilé side-by-side. Nous avons besoin d'un moyen d'informer le compilateur que le Navire* classe existe bel et bien. Et c'est pourquoi l' @class
mot-clé est donc à portée de main.
Pour le mettre en d'autres termes, vous êtes en train de dire: "Croyez-moi, l'homme, Ship
existe vraiment, et vous allez le voir très bientôt". Pour mettre tout cela ensemble:
@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
Maintenant que le compilateur sait qu'il compile BoatYard
, que l' Ship
définition de la classe va bientôt apparaître. Bien sûr, si ce n'est pas, la compilation sera toujours réussir.
Tous les @class
mot clé n'est cependant informer le compilateur que la classe va bientôt venir. C'est pas un remplacement pour l' #import
. Vous devez importer le fichier d'en-tête, ou vous n'aurez pas accès à toute la classe internes:
@class Ship
-(void) example
{
Ship* newShip = [[Ship alloc] init];
}
Cela ne peut pas fonctionner, et échoue avec un message d'erreur indiquant que le Navire est une déclaration anticipée. Une fois que vous #import "Ship.h"
, alors vous serez en mesure de créer l'instance de l'objet.