"预期类型"错误指向方法的返回类型

Oll*_*rst 43 xcode cocoa compiler-errors compilation objective-c

我试图编译,但每次我做,一个方法抛出一个奇怪的"预期的类型"错误.我在标题中有一个方法:

-(ANObject *)generateSomethingForSomethingElse:(NSString *)somethingElse;
Run Code Online (Sandbox Code Playgroud)

该方法的返回类型的错误点.我已经导入ANObject到标题使用#import "ANObject.h"ANObject正在编译精细..

为什么会这样?

Ste*_*uts 93

这与编译源文件的顺序有关.您可能已经意识到在定义之前无法调用方法(请参阅下面的伪代码):

var value = someMethod();

function someMethod()
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

这会导致编译时错误,因为尚未定义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
Run Code Online (Sandbox Code Playgroud)

再一次,因为Ship该类尚未定义,我们还不能参考它.解决这个特殊问题非常简单; 更改编译顺序并编译.我确信你在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
Run Code Online (Sandbox Code Playgroud)

哦,亲爱的,现在我们遇到了问题.这两个不能并排编译.我们需要一种方法来通知编译器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
Run Code Online (Sandbox Code Playgroud)

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

@class但是,所有关键字都会通知编译器该类很快就会出现.它不是替代品#import.您仍然必须导入头文件,否则您将无法访问任何类内部:

@class Ship

-(void) example
{
    Ship* newShip = [[Ship alloc] init];
}
Run Code Online (Sandbox Code Playgroud)

这不起作用,并且会失败并显示一条错误消息,指出Ship是一个前向声明.一旦你#import "Ship.h",那么你将能够创建对象的实例.

  • @ burrows111:经过反思,这是一个非常懒惰的答案; 我写这篇文章的时候一定很匆忙.其他答案解释了如何解决它,但我看不到解释它为什么会发生的原因.我希望编辑的答案可以帮助你. (2认同)

小智 54

当对标头存在循环依赖时,我发现此错误正在发生.检查声明此方法的.h文件是否在ANObject.h中导入

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

Jom*_*nJi 26

你基本上添加

@class ANObject;
Run Code Online (Sandbox Code Playgroud)

在@interface之前!