OC和C、C++一样,利用头文件(header file)和实现文件(implementation file)来区隔代码。用OC编写类的标准方式是:以类名做文件名,分别创建两个文件,头文件后缀用.h,实现文件后缀用.m创建好一个类后,其代码看上去如下所示:
//WGPerson.h
#import <Foundation/Foundation.h>
@interface WGPerson : NSObject
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;
@end
//WGPerson.m
#import "WGPerson.h"
@implementation WGPerson
//todo
@end
如果想在WGPerson中增加一个新的属性,比如WGAddress,一般都会这样写:
//WGPerson.h
#import <Foundation/Foundation.h>
@interface WGPerson : NSObject
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;
@property (nonatomic, strong) WGAddress *address;
@end
然而这么做有个问题,就是在编译引入了WGAddress.h的文件时,WGAddress类并不可见,因此需要一并引入WGAddress.h,所以常见的办法是在WGPerson.h中加入下面这行:
#import "WGAddress.h"
这种办法可行但不够优雅。其实在编译一个使用WGPerson类的文件时,不需要知道WGAddress类的全部细节,只需要知道有个类名叫WGAddress就好,所以我们可以这样声明:
@class WGAddress;
这种声明方法叫做“向前声明”(forward declaring)该类,现在WGPerson的头文件变成了这样:
//WGPerson.h
#import <Foundation/Foundation.h>
@class WGAddress;
@interface WGPerson : NSObject
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;
@property (nonatomic, strong) WGAddress *address;
@end
而在WGPerson类的实现文件中,因为具体用到了WGAddress的细节,所以必须引入WGAddress类的头文件:
//WGPerson.m
#import "WGPerson.h"
#import "WGAddress.h"
@implementation WGPerson
//todo
@end
将引入头文件的时机尽量延后,只在确实有需要的时候才引入,这样就可以减少类的使用者所需引入的头文件数量,减少编译所需时间。
读Effective Objective-C 2.0 有感