OC基礎回顧 (五)源文件組織

  • 拆分接口和實現
    類的@interface指令、公共struct定義、enum常亮、#define和extern全局變量等代碼通常放在頭文件.h文件中。
    所有的實現內容,例如@implementation指令、全局變量的定義、私有struct等代碼都放在.m文件中。
    如果用.mm做文件擴展名,編譯器就會認爲你使用Objective-C++編寫的代碼,這樣就可以同時使用C++和Objective-C來編程了。

  • 導入頭文件
    導入頭文件有兩種方法:使用引號或者尖括號。
    帶尖括號的語句用於引用系統頭文件,是隻讀的。
    而帶引號的語句說明導入的是項目本地的頭文件,是可編輯的。

  • 使用跨文件依賴關係
    依賴關係(dependency)是兩個實體之間的一種關係。
    依賴關係存在於兩個或多個文件之間。
    導入頭文件使頭文件和源文件之間建立了一種緊密的依賴關係。如果頭文件有任何變化,那麼所有依賴它的文件都得重新編譯。
    依賴關係是傳遞的,頭文件之間也可以相互依賴。
    文件導入過於混亂會使依賴關係混亂,從而導致重新編譯花費很長時間。所以巧妙的使用@class指令,可以減少必須導入的頭文件的數量,從而縮短編譯時間。

  • @class
    Objective-C引入了@class關鍵字,用來告訴編譯器:“這是一個類,所以我只會通過指針來引用它”,這樣編譯器就不必知道關於這個類的更多信息,只要瞭解它是通過指針來引用的即可。
    例如:

#import <Cocoa/Cocoa.h>
@interface Car : NSObject
-(void)setEngine:(Engine *)newEngine;
-(Engine *)engine;

-(void)setTire:(Tire *)newTire andIndex:(int)index;
-(Tire *)tireAtIndex:(int)index;
@end //Car

如果我們現在想使用Car.h頭文件,會得到錯誤消息,例如error: expected a type “Tire”,編譯器是說“我無法理解這個”。我們有兩種方法來解決,第一種是在頭文件中#import語句導入Tire.h和Engine.h,這樣編譯器會獲取這兩個類的許多信息。
此外,還有一個更好的方法。因爲在Car.h文件中,它只是通過指針引用了Tire類和Engine類,所以我們可以用@class來實現。

#import <Cocoa/Cocoa.h>
@classTire.h"
@classEngine.h"

@interface Car : NSObject
-(void)setEngine:(Engine *)newEngine;
-(Engine *)engine;

-(void)setTire:(Tire *)newTire andIndex:(int)index;
-(Tire *)tireAtIndex:(int)index;
@end //Car

這樣就足以告知編譯器處理Car類的@interface部分所需要的全部信息了。

@class創建了一個前向引用。這是在告訴編譯器,只能使用被聲明的符號,而不能涉及類的任何細節。
如果有循環依賴關係,@class也很管用。即A類使用了B類,B類也使用了A類,如果試圖通過#import語句讓這兩個類相互引用,那麼就會出現編譯錯誤。但是如果在A.h文件中使用@classB,在 B.h文件中使用@class A,那麼這兩個類就可以相互引用了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章