@class与#import

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

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

warning: receiver 'FooController' is a forward class and corresponding @interface may not exist.

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


如果您看到此警告:

警告:receiver'MyCoolClass'是一个前向类,相应的@interface可能不存在

你需要#import这个文件,但你可以在你的实现文件(.m)中做到这一点,并在你的头文件中使用@class声明。

@class不会(通常)不需要#import文件,它只是将需求更靠近信息的有用位置。

例如

如果你说@class MyCoolClass ,编译器知道它可能会看到类似于:

MyCoolClass *myObject;

除了MyCoolClass是一个有效的类之外,它不必担心任何事情,它应该为指向它的指针MyCoolClass空间(实际上,只是一个指针)。 因此,在你的头文件中, @class 90%的时间。

但是,如果您需要创建或访问myObject的成员,则需要让编译器知道这些方法是什么。 此时(大概在你的实现文件中),你需要#import "MyCoolClass.h" ,告诉编译器除了“这是一个类”之外的附加信息。


三个简单的规则:

  • 仅在#import头文件( .h文件)中导入超类和采用的协议。
  • #import所有类和协议,将消息发送到实现( .m文件)中。
  • 提交其他一切的声明。
  • 如果你在实现文件中进行了前向声明,那么你可能做错了什么。


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

    在定义类的章节下 类接口它描述了为什么这样做:

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

    我希望这有帮助。

    链接地址: http://www.djcxy.com/p/47373.html

    上一篇: @class vs. #import

    下一篇: Copying a structure to Device memory CUDA