为什么@class代替#import for AppDelegate.h中的ViewController?

时间:2012-01-26 10:06:08

标签: objective-c uiviewcontroller

我在Objective C中有一个基本的最佳实践问题。我理解@class#import之间的区别但我不明白为什么默认的Apple Xcode模板会这样做:

AppDelegate.h:

@class ViewController;

的.m:

#import "ViewController.h

如果您可以将后者#import放在.h中,并将ViewController完全从.m中删除,从而简化1行代码。

当然,保存一行代码不是问题,我只是好奇为什么这样做?

3 个答案:

答案 0 :(得分:15)

@class ViewController;是一个前向声明,因此编译器知道名称ViewController应该是什么意思。关键是尽量在头文件中尽可能少#import来加速编译。

想象一下a.h文件#import "b.h"。现在,每个导入a.h的文件都会自动导入b.h,这会增加编译器必须完成的工作量。通过使用前向声明,人们通常可以避免这种额外的导入,从而避免编译器的额外工作。

项目越大,类层次结构和依赖关系越复杂,这些#import就越成问题。因此,养成在可能的情况下使用前向声明的习惯是一个好主意。

编辑:在评论之后,另一个重要的用例浮出水面:解决循环依赖关系。例如,如果类 A 想要引用类 B ,反之亦然,则必须先定义另一个。但是因为他们需要知道另一个我们有一个悖论。它解决了这样的问题:

// Tell the compiler: B will be a class type.
@class B;

// Now we can define A, the compiler has enough
// information to know what B means.
@interface A : NSObject {
    B *b;
}
@end

// Since A is now defined, we can define B.
// Cycle is resolved.
@interface B : NSObject {
    A *a;
}
@end

答案 1 :(得分:2)

前瞻性声明:

@class ClassName;

在头文件中使用,不需要特定的属性,属性或方法信息。

这允许头文件的#import#include,而不会带来#import ClassName.h带来的任何开销。

答案 2 :(得分:0)

#import用于由我们或Apple xcode预定义的类,但@class是我们在定义它之前使用的(它是类的前向声明),在我们的父/或前一个类

所以它告诉编译器在我们的项目中有一个具有此名称的类,因此编译器不会为该类名添加错误。