天天看点

Effective Objective-C(二)Effective Objective-C(二)

Effective Objective-C(二)

在类的头文件中尽量少引入其他头文件

Objective-C中编写类时候创建两个文件,头文件(.h结尾)和实现文件(.m结尾)。创建一个类例子如下:

//EOCPerson.h
#import <Foundation/Foundation.h>

@interface EOCPerson : NSObject
@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@end

//EOCPerson.m
#import "EOCPerson.h"

@implementation EOCPerson
//
@end
           

过段时间后,你创建了一个EOCEmlpoyer的新类,然后想给EOCPerson添加一个属性

于是有:

@interface EOCPerson : NSObject
@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@property (nonatomic, strong) EOCEmployer *employer;
@end
           

并且通常的方法是在EOCPerson.h中加入

#import "EOCEmployer.h"

,这种方法可行但是不够优雅,因为在编译EOCPerson类的文件的时候,不需要知道EOCEmployer类的全部细节,只需要指导一个类名交EOCEmployer就好。于是有个更好的方法来告诉编译器

@class EOCEmployer;

这中方法叫做“向前声明”(forward declaring)该类。

当在EOCPerson类的实现文件中,再引入EOCEmployer类的头文件,因为要知道该类的所有细节。

将引入头文件的时机尽量延后,只在确实需要使用的时候才引入,这样减少类的使用者所引入头文件的数量。如果例中在EOCPerson.h中引入EOCEmployer.h,那么只要引入EOCPerson就会引入EOCEmployer.h的所有内容,若此过程储蓄下去,便会引入许多根本用不到的内容,显然会增加了编译时间。

向前声明也解决了两个类相互引用的问题。假设要为EOCEmployer类加入新增及删除雇员的方法,那么在其头文件中会有一下两方法:

- (void)addEmployee:(EOCPerson *)person;
- (void)removeEmployee:(EOCPerson *)person;
           

此时若要编译EOCEmlpoyee,则编译器必须要知道EOCPerson这个类,而如果要编译EOCPerson则编译器必须要指导EOCEmployee。如果在各自头文件中引入对方的头文件,则会导致”循环引用”(chicken-and-eggs situation)。最终会使两个类中一个无法正确编译。