拆分接口和实现

  • 接口部分统一放头(.h)文件中;
  • 实现部分统一放实现(.m)文件中。

@class

导入头文件在头文件和进行导入的源文件之间建立了一种很强的依赖关系。

为此,Objective-C 提供了一种方法能够减少由依赖关系引起的重新编译所带来的影响。依赖关系问题的存在是因为 Objective-C 编译器需要某些信息才能工作。有时,编译器需要知道类的全部信息,例如它的实例变量配置、它所继承的所有类等。而有的时候,编译器只需要知道类名即可,不需要了解它的整个定义。

Objective-C 引入了关键字 @class 来告诉编译器:“这是一个类,所以我只需要通过指针来引用它。”

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#import <Cocoa/Cocoa.h>
@class Tire;
@class Engine;
@interface Car : NSObject
{
Tire *tires[4];
Engine *engine;
}
- (void) setEngine: (Engine *) newEngine;
- (Engine *) engine;
- (void) setTire: (Tire *) tire
atIndex: (int) index;
- (Tire *) tireAtIndex: (int) index;
- (void) print;
@end // Car

Tips: @class 创建了一个前向引用,就是在告诉编译器:“相信我,以后你会知道这个类到底是什么。但是现在,你只需要知道这些。”

如果有编译依赖关系,@class 也很有用。即 A 类使用 B 类,B 类也使用 A 类。如果试图通过 #import 语句让两个类互相引用,那么最后就会出现编译错误。但是如果在 A.h 中使用 @class B,在 B.h 中使用 @class A ,那么这两个类就可以互相引用了。

注意: 不能在继承的类中通过 @class 语句指向父类。编译器需要先知道所有关于超类的信息才能成功地为其子类编译 @interface 。它需要了解父类实例变量的配置(数据类型、大小和排序)。