我试图编译,但每次我都这样做,一个方法抛出一个奇怪的“预期的类型”错误。我在标题中有一个方法:
-(ANObject *)generateSomethingForSomethingElse:(NSString *)somethingElse;
此方法的返回类型的错误点。我已使用ANObject
将#import "ANObject.h"
导入标题,ANObject
正在编译中。{/ p>
为什么会这样?
答案 0 :(得分:93)
这与编译源文件的顺序有关。您可能已经意识到在定义之前无法调用方法(参见下面的伪代码):
var value = someMethod();
function someMethod()
{
...
}
这会导致编译时错误,因为尚未定义someMethod()。课程也是如此。编译器一个接一个地编译类。
因此,如果您想象在编译之前将所有类放入一个巨大的文件中,您可能已经能够看到该问题。我们来看看Ship
和BoatYard
类:
@interface BoatYard : NSObject
@property (nonatomic, retain) Ship* currentShip;
@end
@interface Ship : NSObject
@property (nonatomic, retain) NSString* name;
@property (nonatomic, assign) float weight;
@end
再一次,因为尚未定义Ship
类,我们还不能参考它。解决这个特殊问题非常简单;更改编译顺序并编译。我相信你对XCode中的这个屏幕很熟悉:
但是你知道你可以在列表中上下拖动文件吗?这会更改文件编译的顺序。因此,只需将Ship
类移到BoatYard
类之上,一切都很好。
但是,如果您不想这样做,或者更重要的是,如果两个对象之间存在循环关系会怎么样?让我们通过添加对BoatYard
所在的当前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
亲爱的,现在我们遇到了问题。这两个不能并排编译。我们需要一种方法来通知编译器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];
}
这不起作用,并且会失败并显示一条错误消息,指出Ship是一个前向声明。一旦#import "Ship.h"
,您就可以创建对象的实例。
答案 1 :(得分:54)
当我对标头有循环依赖时,我发现这个错误正在变化。检查声明此方法的.h文件是否在ANObject.h中导入
答案 2 :(得分:25)
你基本上添加
@class ANObject;
@interface之前的!
答案 3 :(得分:4)
因此,出于某种原因,我在尝试使用参数中的枚举类型设置方法时遇到此错误。像这样:
- (void)foo:(MyEnumVariable)enumVariable;
我以前曾经这样使用它并且从来没有问题,但现在我做了。我检查了循环依赖,但没有找到。我也多次检查错别字,没有骰子。最终解决我的问题的是在我想要访问变量之前添加“枚举”。像这样:
- (void)foo:(enum MyEnumVariable)enumVariable;
{
enum MyEnumVariable anotherEnumVariable;
}
答案 4 :(得分:1)
通常当我看到这样的错误时,因为我在前一行上有拼写错误,例如额外或缺少括号或其他内容。
答案 5 :(得分:1)
当变量类型拼写错误时,我收到此消息。见下文
e.g。
-(void)takeSimulatorSafePhotoWithPopoverFrame:(GCRect)popoverFrame {
而不是......
-(void)takeSimulatorSafePhotoWithPopoverFrame:(CGRect)popoverFrame {
答案 6 :(得分:1)
这可能听起来很愚蠢,但错误的炮击或错误使用大写/小写字母的情况就是这样。
答案 7 :(得分:0)
奇怪的是,改变我的导入顺序已经解决了这个问题...尝试在导入所有其他导入后将导入移动到底部。