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

joh*_*ers 3 objective-c uiviewcontroller

我有一个基本的最佳实践问题的目的C.我明白之间的差别@class#import,但我不明白为什么默认苹果的Xcode模板,这样做:

AppDelegate.h:

@class ViewController;

.M:

#import "ViewController.h

当你可以,而不是仅仅把后者#import.h离开的提ViewController出的.m完全,从而通过1行代码简化.

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

Dar*_*ust 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
Run Code Online (Sandbox Code Playgroud)

  • Xcode只将`.m`文件传递给编译器,一次一个.然后`.m`文件导入它需要的所有`.h`文件.这就是为什么你可以设置`.m`文件的*Target Membership*,而不是`.h`文件.编译器不会将`.m`和`.h`文件视为成对,它不知道(也不关心)两者之间的任何关系.实际上,无论如何你都可以命名你的`.h`文件,扩展名`.h`只是一个约定. (2认同)