2011-11-12 74 views
40

我试图编译,但每次我做,一个方法会抛出一个奇怪的“预期类型”错误。我在头文件中有一个方法:“预期类型”错误指向方法的返回类型

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

该方法返回类型的错误点。我已经使用#import "ANObject.h"ANObjectANObject导入标题中。

为什么会发生这种情况?

+0

似乎很好..你可以发布你的代码的一部分? – Devarshi

+0

也...是其他框架的ANObject部分? – Devarshi

+4

请编辑您的问题以包含ANObject.h的内容和提供您问题的标题。并且请显示您的实际代码,而不是可能不包含问题的组成代码。 –

回答

89

这是做的顺序的源文件编译您已经大概知道,你不能调用定义之前的方法(见下面的伪代码):

var value = someMethod(); 

function someMethod() 
{ 
    ... 
} 

这会导致编译时错误,因为someMethod()尚未定义。类也是如此。类由编译器依次编译。

所以,如果你想象所有的类在编译之前被放入一个巨大的文件中,你可能已经能够看到这个问题。让我们来看看ShipBoatYard类:

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

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

再次,因为Ship类尚未定义,我们不能引用它。解决这个问题非常简单,改变编译顺序并编译。我敢肯定,你familliar与此屏幕的XCode:

但你知道,你最多可以在列表中上下拖动文件?这改变了文件将被编译的顺序。因此,只需将Ship类移动到BoatYard类以上,并且一切都很好。

但是,如果您不想这么做,或者更重要的是,如果两个对象之间存在循环关系会怎么样呢?让我们通过将参考目前BoatYardShip是增加该对象图的复杂性:

@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 

哦,亲爱的,我们现在有一个问题。这两个不能并行编译。我们需要一种方法告知编译器Ship *类真的存在。这就是为什么@class关键字非常方便。要说得通俗一点,你说的是:“相信我,Ship确实存在,你很快就会看到它。”为了把它放在一起:

@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 

现在编译器知道,因为它编译BoatYard,一个Ship类定义将很快出现。当然,如果没有,汇编仍然会成功。

但是,所有@class关键字都会通知编译器该类很快就会出现。它是不是代替#import。你还必须导入头文件,否则你不会有任何类的内部访问:

@class Ship 

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

这可不行,而且会失败,错误消息说,船舶是一个向前声明。一旦你#import "Ship.h",那么你将能够创建对象的实例。

+0

史蒂夫,你能解释为什么会发生这种情况吗?欢呼声 – theiOSDude

+2

@ burrows111:经过反思,这是一个非常懒惰的答案;我写这本书时一定很匆忙。其他答案解释了如何解决它,但我看不到解释它为什么会发生的解释。我希望编辑的答案可以帮助你。 –

+0

使更多的意义!欢呼伙计! – theiOSDude

1

通常当我看到这样的错误时,是因为我在上一行有一个错字,比如一个额外的或缺少的括号或其他东西。 。

52

我发现这个错误发生在头部有循环依赖的时候。检查哪里将此方法声明.h文件中ANObject.h

+2

是的,由于循环依赖性,我得到了类似的错误。通过在接口文件中包含前向类声明并在实现中导入头文件来避免它。 –

+0

这对我更好:),谢谢! – mm24

22

导入你基本上@interface前添加

@class ANObject; 

+0

我不知道如何,但这解决了我的问题。 #import does not work and @class works .. – dreampowder

+0

好,它适合你:)总是乐于帮忙 – JomanJi

1

当变量类型拼写错误时,我收到了此消息。请参阅下面的内容

例如

-(void)takeSimulatorSafePhotoWithPopoverFrame:(GCRect)popoverFrame { 

,而不是.....

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

花了我足够长的时间来弄清楚CGRect和GCRect的区别。 – OlivaresF

4

所以,出于某种原因而试图设置方法与参数枚举类型我得到这个错误。像这样:

- (void)foo:(MyEnumVariable)enumVariable; 

我以前曾经这样使用过它,从来没有问题,但现在我做了。我检查了循环依赖,并且找不到任何东西。我也多次检查错别字,没有骰子。最终解决我的问题的是在我想访问变量之前添加'枚举'。像这样:

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

这听起来很蠢,但炮击错误或错误使用大/小写letterwrong情况下,这个的。

+0

我讨厌那些字母错误的情况! – DiscDev

0

奇怪的是,更改我的导入顺序已经解决了这个问题...尝试在所有其他导入后将导入移动到底部。