根据我的理解,在ClassA需要包含ClassB标头,而ClassB需要包含ClassA标头以避免任何循环包含的情况下,应该使用前向类声明。我还理解#import是一个简单的ifndef,因此include只发生一次。
我的问题是:什么时候使用#import,什么时候使用@class?有时如果我使用@class声明,我看到一个常见的编译器警告,如下所示:
警告:接收端FooController是转发类,对应的@interface可能不存在。
我真的很想理解这一点,而不是仅仅删除@class forward-declaration并抛出一个#import来沉默编译器给我的警告。
如果你试图在头文件中声明一个变量,或者一个属性,你还没有导入,你会得到一个错误,说编译器不知道这个类。
你的第一个想法可能是导入它。
在某些情况下,这可能会导致问题。
例如,如果你在头文件中实现了一堆c方法,或者结构,或者类似的东西,因为它们不应该被多次导入。
因此你可以用@class告诉编译器:
我知道你不知道那门课,但它确实存在。它将被导入或在其他地方实现
它基本上告诉编译器关闭并编译,即使它不确定这个类是否会被实现。
通常在.m文件中使用#import,在.h文件中使用@class。
如果你试图在头文件中声明一个变量,或者一个属性,你还没有导入,你会得到一个错误,说编译器不知道这个类。
你的第一个想法可能是导入它。
在某些情况下,这可能会导致问题。
例如,如果你在头文件中实现了一堆c方法,或者结构,或者类似的东西,因为它们不应该被多次导入。
因此你可以用@class告诉编译器:
我知道你不知道那门课,但它确实存在。它将被导入或在其他地方实现
它基本上告诉编译器关闭并编译,即使它不确定这个类是否会被实现。
通常在.m文件中使用#import,在.h文件中使用@class。
如果你看到这个警告:
警告:接收端MyCoolClass是转发类,对应的@interface可能不存在
您需要#导入文件,但是您可以在实现文件(.m)中这样做,并在头文件中使用@class声明。
@class并不(通常)消除#import文件的需要,它只是把需求移到更接近信息有用的地方。
例如
如果你说@class MyCoolClass,编译器知道它可能会看到类似这样的东西:
MyCoolClass *myObject;
除了MyCoolClass是一个有效的类之外,它不需要担心其他任何事情,并且它应该为指向它的指针保留空间(实际上,只是一个指针)。因此,在头文件中,@class占据了90%的时间。
然而,如果你需要创建或访问myObject的成员,你需要让编译器知道这些方法是什么。在这一点上(大概在你的实现文件中),你需要#import "MyCoolClass.h",告诉编译器除了"这是一个类"之外的其他信息。