44 votes

Erreur "type attendu" indiquant le type de retour d'une méthode

J'ai essayé de compiler, mais chaque fois que je le fais, une méthode génère une erreur "attendue d'un type". J'ai une méthode dans l'en-tête:

 -(ANObject *)generateSomethingForSomethingElse:(NSString *)somethingElse;
 

L'erreur pointe sur le type de retour pour cette méthode. J'ai importé ANObject dans l'en-tête en utilisant #import "ANObject.h" et ANObject compilation est bien faite ..

Pourquoi cela arrive-t-il?

99voto

Steve Rukuts Points 2708

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.

56voto

RENA Points 411

J'ai trouvé cette erreur quand il y a une dépendance circulaire sur les en-têtes. Vérifiez si le fichier .h dans lequel vous déclarez cette méthode est importé dans ANObject.h

27voto

JomanJi Points 528

Vous ajoutez essentiellement

 @class AnyObject;
 

avant @interface!

4voto

OlivaresF Points 652

Donc, pour une raison quelconque, je recevais cette erreur en essayant de définir une méthode avec un type enum dans les paramètres. Ainsi:

 - (void)foo:(MyEnumVariable)enumVariable;
 

Je l'avais précédemment utilisé comme ça et je n'avais jamais eu de problème, mais maintenant je l'ai fait. J'ai vérifié la dépendance circulaire et n'ai pu en trouver aucune. J'ai également vérifié les fautes de frappe à plusieurs reprises et pas de dés. Ce qui a fini par résoudre mon problème a été d’ajouter «enum» avant que je ne souhaite accéder à la variable. Ainsi:

 - (void)foo:(enum MyEnumVariable)enumVariable;
{
     enum MyEnumVariable anotherEnumVariable;
}
 

1voto

Dave DeLong Points 156978

Habituellement, quand je vois une erreur comme celle-ci, c'est parce que j'ai une faute de frappe sur une ligne précédente, telle qu'une parenthèse supplémentaire ou manquante, ou quelque chose du genre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X