在过去一个月左右的时间里,我一直在教自己Objective-C(我是一名Java负责人),现在我的大脑已经被大部分包围了。有一件事让我感到困惑:通过@class导入一个类与进行#import之间的区别是什么?
一个比另一个好,还是在某些情况下我需要使用一个而不是另一个?到目前为止我一直在使用#import。
答案 0 :(得分:66)
#import
将有问题的整个头文件带入当前文件中;还包括那些文件#import
的文件。另一方面,@ class(当在一行上使用某些类名时),只是告诉编译器“嘿,你很快就会看到一个新的令牌;它是一个类,所以这样对待它”。
当你有'循环包含'的潜力时,这非常有用;即,Object1.h引用Object2,Object2.h引用Object1。如果你将#import
两个文件放到另一个文件中,那么编译器在尝试#import
Object1.h时会感到困惑,查看它并看到Object2.h;它尝试#import
Object2.h,并看到Object1.h等。
另一方面,如果每个文件都有@class Object1;
或@class Object2;
,那么就没有循环引用。确保在您的实现(.m)文件中实际#import
所需的标头。
答案 1 :(得分:27)
@class
被称为前向声明。你基本上告诉编译器该类存在但不是关于该类的任何内容。因此,它不知道像超类这样的东西以及它声明的方法。
作为一般规则,如果可能,请使用.h中的@class
和.m中的#import
。就像路易斯说的那样,它将有助于加快编译时间。有时您需要在标题中#import
一个类。我现在能想到的案例是:
在这些情况下,您必须#import
声明类或协议的头文件,因为编译器需要知道其父类的完整类层次结构并实现协议。
FWIW,你也可以转发声明协议,只要你没有实现它们:
@protocol SomeProtocol;
@interface ...
- (id<SomeProtocol>)someMethod;
@end
答案 2 :(得分:5)
您要记住的另一件事是#imports减慢了编译时间,因为这意味着编译器需要提取并处理更多的头文件。这主要是通过使用预编译的头文件来掩盖的,但是我偶尔会将项目转换为corss导入的每个头文件,而不是在适当的地方使用@class,修复它们可以缩短编译时间。这是一个微妙的方式,系统强化了这样一个事实,即如果你只使用你真正需要的东西,那就更快了。
作为一般规则,我总是在头文件中使用@class声明,并且只#import超类。这符合Ben的建议,但我认为值得注意的是,即使你不担心循环引用,如果可以的话,最好限制头文件中的#imports。