2011-11-12 19 views
40

He intentado compilar, pero cada vez que lo hago, un método arroja un extraño error "esperado un tipo". Tengo un método en el encabezado:Error "Se esperaba un tipo" que apunte al tipo de devolución de un método

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

Los puntos de error en el tipo de cambio de este método. He importado ANObject en la cabecera usando #import "ANObject.h" y ANObject está compilando bien ..

Por qué sucede esto?

+0

parece estar bien ... ¿puedes publicar una parte de tu código? – Devarshi

+0

también ... ¿es ANObject parte de algún otro framework? – Devarshi

+4

Edite su pregunta para incluir tanto el contenido de ANObject.hy el encabezado que le está dando el problema. Y muestre su código real, no el código inventado que puede no incluir el problema. –

Respuesta

89

Esto tiene que ver con el orden en que los archivos de origen se compilan en Ya está probablemente consciente de que no se puede llamar a un método antes de que se define (véase más adelante pseudocódigo):

var value = someMethod(); 

function someMethod() 
{ 
    ... 
} 

Este causaría un error en tiempo de compilación porque someMethod() aún no se ha definido. Lo mismo es cierto de las clases. Las clases son compiladas una después de la otra por el compilador.

Por lo tanto, si imagina que todas las clases se colocan en un archivo gigante antes de la compilación, es posible que ya pueda ver el problema. Echemos un vistazo a la clase Ship y BoatYard:

@interface BoatYard : NSObject 
@property (nonatomic, retain) Ship* currentShip; 
@end 

@interface Ship : NSObject 
@property (nonatomic, retain) NSString* name; 
@property (nonatomic, assign) float weight; 
@end 

Una vez más, porque la clase Ship aún no se ha definido, no podemos referirnos a ella todavía. Resolver este problema en particular es bastante simple; cambiar el orden de compilación y compilar. Estoy seguro de que está familliar con esta pantalla en XCode:

Pero ¿Sabe usted que puede arrastrar los archivos arriba y hacia abajo en la lista? Esto cambia el orden en que se compilarán los archivos. Por lo tanto, solo mueve la clase Ship por encima de la clase BoatYard, y todo está bien.

Pero, ¿qué pasa si no quieres hacer eso, o más importante, qué pasa si hay una relación circular entre los dos objetos? Vamos a aumentar la complejidad de ese diagrama de objetos mediante la adición de una referencia a la corriente BoatYard que el 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 querido, ahora tenemos un problema. Estos dos no pueden compilarse uno al lado del otro. Necesitamos una manera de informar al compilador que la clase Ship * realmente existe. Y esta es la razón por la cual la palabra clave @class es muy útil.

Para ponerlo en términos sencillos, dices, "créeme, hombre, Ship realmente existe, y lo verás muy pronto". Para poner todo junto:

@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 

Ahora el compilador sabe ya que compila BoatYard, que una definición de clase Ship pronto aparecerá. Por supuesto, si no lo hace, la compilación seguirá teniendo éxito.

Toda la palabra clave @class sin embargo, le informa al compilador que la clase llegará pronto. Es no un reemplazo para #import.No obstante, debe importar el archivo de cabecera, o que no tendrá acceso a ninguna de las partes internas de clase:

@class Ship 

-(void) example 
{ 
    Ship* newShip = [[Ship alloc] init]; 
} 

Esto no puede trabajar, y se producirá un error con un mensaje de error diciendo que la nave es una declaración hacia adelante. Una vez que #import "Ship.h", podrá crear la instancia del objeto.

+0

Steve, ¿puedes explicar la razón por la que esto sucede? vítores – theiOSDude

+2

@ burrows111: Después de reflexionar, esa es una respuesta bastante floja; Debo haber tenido prisa cuando lo escribí. Las otras respuestas explican cómo resolverlo, pero no puedo ver uno que explique por qué sucede. Espero que la respuesta editada te ayude. –

+0

tiene mucho más sentido! ¡salud Amigo! – theiOSDude

1

Normalmente cuando veo un error como este es porque tengo un error tipográfico en una línea anterior, como un paréntesis extra o faltante o algo así. .

52

Encontré este error cuando existe una dependencia circular en los encabezados. Compruebe si el archivo .h, donde se declara que este método ha sido importada en ANObject.h

+2

Sí, recibí un error similar debido a la dependencia circular. Se evitó al incluir la declaración de clase de reenvío en el archivo de interfaz e importar el archivo de encabezado en la implementación. –

+0

Esto funciona mejor para mí :), ¡gracias! – mm24

22

Es, básicamente, agrega

@class ANObject; 

antes @interface!

+0

no sé cómo pero esto resolvió mi problema. #import doesnt work y @class funciona ... – dreampowder

+0

Bueno, eso funciona para usted :) Siempre feliz de ayudar – JomanJi

1

Recibí este mensaje cuando el tipo de variable estaba mal escrito. Consulte a continuación esto a continuación

p.

-(void)takeSimulatorSafePhotoWithPopoverFrame:(GCRect)popoverFrame { 

en lugar de .....

-(void)takeSimulatorSafePhotoWithPopoverFrame:(CGRect)popoverFrame { 
+3

Me llevó lo suficiente como para darse cuenta de que la diferencia es CGRect y GCRect. – OlivaresF

4

Así que, por alguna razón que estaba recibiendo este error al intentar establecer un método con un tipo de enumeración de los parámetros. De esta manera:

- (void)foo:(MyEnumVariable)enumVariable; 

Lo había usado anteriormente y nunca tuve un problema, pero ahora lo hice. Revisé la dependencia circular y no pude encontrar ninguna. También verifiqué los errores tipográficos varias veces y sin dados. Lo que terminó resolviendo mi problema fue agregar 'enum' antes de que quisiera acceder a la variable. De este modo:

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

Puede sonar tonto, pero el bombardeo equivocado o mal uso de la caja de mayúsculas/minúsculas letterwrong esto.

+0

¡Odio esos casos de cartas! – DiscDev

0

Por extraño que parezca, cambiar el orden de mis importaciones ha solucionado esto en el pasado ... Intente mover la importación a la parte inferior después de todas sus otras importaciones.

Cuestiones relacionadas