我try 过编译,但每次都有一个方法抛出一个奇怪的"expected a type"错误.我在标题中有一个方法:

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

错误指向此方法的返回类型.我已经使用#import "ANObject.h"ANObject导入到标题中,ANObject可以编译..

为什么会这样?

推荐答案

这与源文件的编译顺序有关.您可能已经知道,在定义方法之前不能调用它(请参见下面的伪代码):

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"后,就可以创建对象的实例.

Objective-c相关问答推荐

将 NSMutableAttributedString 转换为 NSString

如何从 C 方法调用 Objective-C 方法?

保存 UIImage,以错误的方向加载它

定义缓存变量时在objective-c中使用static关键字

iOS 指定初始化器:使用 NS_DESIGNATED_INITIALIZER

如果安装了应用程序,如何以编程方式判断?

如何知道 NSAssert 在发布版本中是否被禁用?

CoreData 关系故障?

如何更改 UICollectionView 中的滚动方向?

如何在 iPhone 上显示来自 API 的 HTML 文本?

应用程序内部的Gift App

iPhone - 时区便利方法之间的差异

[NSNull null] 和 nil 有什么区别?

如何将小时数添加到 NSDate?

Core Data使用原始数据类型的标量属性复选框

隐藏 NSTableView 标头?

立即检测 iOS 方向变化

允许用户从 UILabel 中 Select 文本进行复制

在objective c中以自定义格式获取当前时间

Xcode没有编译任何项目? 'clang 失败,退出代码 255'