天天看點

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)。最終會使兩個類中一個無法正确編譯。