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

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

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

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


当前回答

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

其他回答

我看到很多“这样做”,但我没有看到任何“为什么”的答案。

那么:为什么在头文件中使用@class,而在实现中使用#import呢?一直使用@class和#import会使你的工作加倍。除非你使用继承。在这种情况下,您将为单个@class #import多次。然后,如果您突然决定不再需要访问某个声明,您必须记得从多个不同的文件中删除。

由于#import的性质,多次导入同一个文件不是问题。 编译性能也不是真正的问题。如果是的话,我们就不会在几乎每个头文件中都使用#importing Cocoa/Cocoa.h之类的代码了。

有关文件依赖关系& #import & @class的更多信息,请查看以下内容:

http://qualitycoding.org/file-dependencies/ 这是篇好文章

文章摘要

imports in header files: #import the superclass you’re inheriting, and the protocols you’re implementing. Forward-declare everything else (unless it comes from a framework with a master header). Try to eliminate all other #imports. Declare protocols in their own headers to reduce dependencies. Too many forward declarations? You have a Large Class. imports in implementation files: Eliminate cruft #imports that aren’t used. If a method delegates to another object and returns what it gets back, try to forward-declare that object instead of #importing it. If including a module forces you to include level after level of successive dependencies, you may have a set of classes that wants to become a library. Build it as a separate library with a master header, so everything can be brought in as a single prebuilt chunk. Too many #imports? You have a Large Class.

如果需要,在头文件中使用前向声明,并为在实现中使用的任何类导入头文件。换句话说,您总是#import您在实现中使用的文件,如果您需要在头文件中引用一个类,也可以使用forward声明。

例外的是,你应该在头文件中导入一个类或正式协议(在这种情况下,你不需要在实现中导入它)。

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

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

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

可以把@class看作是告诉编译器“相信我,这是存在的”。

可以把#import看作是复制-粘贴。

出于多种原因,您希望最小化导入的数量。在没有任何研究的情况下,首先想到的是它减少了编译时间。

注意,当从类继承时,不能简单地使用前向声明。您需要导入文件,以便您声明的类知道它是如何定义的。