Effective Objective-C 2.0讀書筆記(一)-如何減少標頭檔案的引入

scar1900發表於2019-09-02

決定用一個讀書筆記作為自己掘金部落格的第一篇會比較好,壓力也比較小。最近在讀《編寫高質量iOS與OS X程式碼的52個有效方法》,覺得應該記下來的細小的點非常多,希望大家看了我的讀書筆記也能有所裨益吧。

如何減少標頭檔案的引入

有時候在OC的標頭檔案宣告一些屬性或者方法,此時可能會依賴一些其他的類,常規的做法是直接引入依賴類的標頭檔案。比如:

#import <Foundation/Foundation.h>
#import "Head.h"

@interface APerson:NSObject
@property(nonatomic,strong)Head *personHead;
@end
複製程式碼

這裡,由於APerson需要宣告一個Head型別的屬性,於是引入了Head.h,這麼做有一個問題,如果APerson宣告中並不需要Head這個類的所有細節,比如上面例子所示,僅僅只是想要宣告personHead的型別是Head。此時,如果僅僅只是Head.h檔案進行了改動,那麼APerson和其他引入Head.h的檔案都要重新進行編譯,對於大型專案來說,編譯的效率會變得非常低下。

那麼該如何優雅的解決這個問題呢?

可以通過@class關鍵字告訴編譯器,當前依賴的Head類我並不需要所有的細節,我只要知道有一個類的名字叫做Head就可以,所以上述程式碼就變成了這樣:

#import <Foundation/Foundation.h>

@class Head;

@interface APerson:NSObject
@property(nonatomic,strong)Head *personHead;
@end
複製程式碼

這叫做向前宣告(forward declaring)該類,向前宣告後,在實現檔案(APerson.m)中引入需要的標頭檔案即可,也就是在需要使用Head類時,獲取這個類的具體介面細節。這樣就可以把引入標頭檔案的時機延遲到明確需要的時候,提高編譯效率。

更多的時候,@class可以完美的解決兩個類標頭檔案相互引入的問題,避免編譯錯誤

在理解以上概念之後,其實就可以區分什麼場景該用#import,什麼場景該用@class。很關鍵的一點就是是否需要知道依賴類的介面細節。下面有兩點就是典型的不能使用@class的場景:

  • 子類繼承父類後,需要引入父類的標頭檔案,此時只能使用#import。因為在編譯時,子類的標頭檔案需要知道父類的介面細節才能完成繼承。
  • 當前類用到了依賴的類的介面,涉及到了依賴類的屬性和方法,此時也必須要用#import

相關文章