根据我的理解,在ClassA需要包含ClassB标头,而ClassB需要包含ClassA标头以避免任何循环包含的情况下,应该使用前向类声明。我还理解#import是一个简单的ifndef,因此include只发生一次。

我的问题是:什么时候使用#import,什么时候使用@class?有时如果我使用@class声明,我看到一个常见的编译器警告,如下所示:

警告:接收端FooController是转发类,对应的@interface可能不存在。

我真的很想理解这一点,而不是仅仅删除@class forward-declaration并抛出一个#import来沉默编译器给我的警告。


当前回答

当我发展的时候,我脑中只有三件事,这三件事从来不会给我带来任何问题。

导入超类 导入父类(当您有子类和父类时) 在项目外部导入类(比如在框架和库中)

对于所有其他类(我的项目中的子类和子类),我通过forward-class声明它们。

其他回答

查看关于ADC的Objective-C编程语言文档

在定义类|类接口一节中,它描述了为什么这样做:

@class指令最大限度地减少了编译器和链接器看到的代码量,因此是给出类名正向声明的最简单方法。由于简单,它避免了导入仍然导入其他文件的文件时可能出现的潜在问题。例如,如果一个类声明了另一个类的静态类型实例变量,并且它们的两个接口文件相互导入,那么两个类都不能正确编译。

当我发展的时候,我脑中只有三件事,这三件事从来不会给我带来任何问题。

导入超类 导入父类(当您有子类和父类时) 在项目外部导入类(比如在框架和库中)

对于所有其他类(我的项目中的子类和子类),我通过forward-class声明它们。

向前声明只是为了防止编译器显示错误。

编译器会知道你在头文件中声明的类的名称。

常见的做法是在头文件中使用@class(但仍然需要#import父类),在实现文件中使用#import。这样可以避免任何圆形夹杂物,而且效果很好。

三个简单的规则:

只在头文件(.h文件)中#导入超类和采用的协议。 #导入所有类和协议,你发送消息到实现(。m文件)。 其他所有东西的前向声明。

如果在实现文件中进行前向声明,则可能会出错。