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

发布于 2024-12-15 17:06:12 字数 293 浏览 2 评论 0原文

我尝试编译,但每次编译时,一个方法都会抛出一个奇怪的“预期类型”错误。我在标头中有一个方法:

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

错误指向该方法的返回类型。我已使用 #import "ANObject.h"ANObject 导入标头,并且 ANObject 编译正常。

为什么会发生这种情况?

I've attempted to compile, but every time I do, one method throws a strange "expected a type" error. I have a method in the header:

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

The error points at the return type for this method. I've imported ANObject into the header using #import "ANObject.h" and ANObject is compiling fine..

Why is this happening?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

ˉ厌 2024-12-22 17:06:12

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

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 类尚未定义,所以我们无法引用它然而。解决这个特殊问题非常简单;更改编译顺序并编译。我相信您熟悉 XCode 中的这个屏幕:

但是您是否知道可以在列表中上下拖动文件?这会更改文件的编译顺序。因此,只需将 Ship 类移到 BoatYard 类上方,一切就都很好。

但是,如果您不想这样做怎么办,或者更重要的是,如果两个对象之间存在循环关系怎么办?让我们通过添加对 Ship 所在的当前 BoatYard 的引用来增加该对象图的复杂性:

@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",您将能够创建该对象的实例。

This is to do with the order that the source files are compiled in. You are already probably aware that you can't call a method before it is defined (see below pseudocode):

var value = someMethod();

function someMethod()
{
    ...
}

This would cause a compile-time error because someMethod() has not yet been defined. The same is true of classes. Classes are compiled one after the other by the compiler.

So, if you imagine all the classes being put into a giant file before compilation, you might be able to already see the issue. Let's look at the Ship and BoatYard class:

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

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

Once again, because the Ship class has not yet been defined, we can't refer to it yet. Solving this particular problem is pretty simple; change the compilation order and compile. I'm sure you're familliar with this screen in XCode:

But are you aware that you can drag the files up and down in the list? This changes the order that the files will be compiled in. Therefore, just move the Ship class above the BoatYard class, and all is good.

But, what if you don't want to do that, or more importantly, what if there is a circular relationship between the two objects? Let's increase the complexity of that object diagram by adding a reference to the current BoatYard that the Ship is in:

@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 dear, now we have a problem. These two can't be compiled side-by-side. We need a way to inform the compiler that the Ship* class really does exist. And this is why the @class keyword is so handy.

To put it in layman's terms, you're saying, "Trust me man, Ship really does exist, and you'll see it really soon". To put it all together:

@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

Now the compiler knows as it compiles BoatYard, that a Ship class definition will soon appear. Of course, if it doesn't, the compilation will still succeed.

All the @class keyword does however is inform the compiler that the class will soon come along. It is not a replacement for #import. You still must import the header file, or you will not have access to any of the class internals:

@class Ship

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

This cannot work, and will fail with an error message saying that Ship is a forward declaration. Once you #import "Ship.h", then you will be able to create the instance of the object.

寂寞陪衬 2024-12-22 17:06:12

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

I found this error hapenning when there is circular dependency on the headers. Check if the .h file where you declare this method is imported in ANObject.h

蹲在坟头点根烟 2024-12-22 17:06:12

你基本上

@class ANObject;

在@interface之前添加!

You basically add

@class ANObject;

before @interface!

谈场末日恋爱 2024-12-22 17:06:12

因此,由于某种原因,我在尝试设置参数中具有枚举类型的方法时收到此错误。就像这样:

- (void)foo:(MyEnumVariable)enumVariable;

我以前像这样使用它并且从未遇到过问题,但现在我遇到了。我检查了循环依赖,但没有找到。我还多次检查了拼写错误,没有骰子。最终解决我的问题的是在我想访问变量之前添加“enum”。就像这样:

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

So, for some reason I was getting this error while trying to set a method with an enum type in the parameters. Like so:

- (void)foo:(MyEnumVariable)enumVariable;

I had previously used it like this and never had an issue but now I did. I checked for circular dependency and could find none. I also checked for typos multiple times and no dice. What ended up solving my issue was to adding 'enum' before I wanted to access the variable. Like so:

- (void)foo:(enum MyEnumVariable)enumVariable;
{
     enum MyEnumVariable anotherEnumVariable;
}
朦胧时间 2024-12-22 17:06:12

通常,当我看到这样的错误时,是因为我在前一行中出现了拼写错误,例如多余或缺少括号或其他内容。

Usually when I see an error like this it's because I have a typo on a previous line, such as an extra or missing parenthesis or something.

仙女 2024-12-22 17:06:12

这可能听起来很愚蠢,但错误的脱壳或错误使用大写/小写字母错误的大小写。

It may sound stupid, but wrong shelling or wrong use of uppercase/lowercase letterwrong case this.

秋风の叶未落 2024-12-22 17:06:12

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

例如

-(void)takeSimulatorSafePhotoWithPopoverFrame:(GCRect)popoverFrame {

而不是......

-(void)takeSimulatorSafePhotoWithPopoverFrame:(CGRect)popoverFrame {

I got this message, when the variable type was misspelled. See below this below

e.g.

-(void)takeSimulatorSafePhotoWithPopoverFrame:(GCRect)popoverFrame {

instead of.....

-(void)takeSimulatorSafePhotoWithPopoverFrame:(CGRect)popoverFrame {
小ぇ时光︴ 2024-12-22 17:06:12

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

Strangely enough, changing the order of my imports has fixed this in the past... Try moving the import to the bottom after all your other imports.

痴者 2024-12-22 17:06:12

我通过将 @class class_name 添加到 .h 文件来解决它

I solved it by adding @class class_name to the .h file

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文