決定用一個讀書筆記作為自己掘金部落格的第一篇會比較好,壓力也比較小。最近在讀《編寫高質量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