"頭文件" 與 "實現(xiàn)文件"
- Objective-C語言編寫"類"的標(biāo)注方式為: 以類名做文件名, 分別創(chuàng)建兩個文件, 頭文件后綴用.h, 實現(xiàn)文件后綴用.m。
#include指令
#include
是C語言的預(yù)處理指令之一,所謂預(yù)處理否彩,就是在編譯之前做的處理瑞凑。預(yù)處理指令一般以 # 開頭。#include
指令后面會跟著一個文件名陡叠,預(yù)處理器發(fā)現(xiàn)#include
指令后玩郊,就會根據(jù)文件名去查找文件,并把這個文件的內(nèi)容包含到當(dāng)前文件中枉阵。被包含文件中的文本將替換源文件中的
#include
指令译红,就像你把被包含文件中的全部內(nèi)容拷貝到這個#include
指令所在的位置一樣。如果要想使用聲明在.h頭文件 的函數(shù)兴溜,就必須先用
#include
指令包含函數(shù)所在的.h頭文件侦厚。#include
指令不僅僅限于.h頭文件,可以包含任何編譯器能識別的C/C++代碼文件拙徽,包括.c刨沦、.hpp、.cpp等膘怕,甚至.txt想诅、.abc等等都可以。
#include""
與#include<>
當(dāng)包含我們自己寫的文件就是使用
#include ""
;當(dāng)包含系統(tǒng)??提供的頭文件的時候,就是用#include <>
岛心。注意:include
語句之后不需要加";"
(因為#include
它為一個預(yù)處理指令
,不是一個語句)-
#include""
與#include<>
二者的區(qū)別在于:當(dāng)被include的文件路徑不是絕對路徑的時候来破,有不同的搜索順序。-
#include""
搜索順序:
1.先在這條include指令的父文件所在文件夾內(nèi)搜索忘古,所謂的父文件讳癌,就是這條include指令所在的文件;
2.如果上一步找不到存皂,則在父文件的父文件所在文件夾內(nèi)搜索晌坤;
3.如果上一步找不到,則在編譯器設(shè)置的include路徑內(nèi)搜索旦袋;
4.如果上一步找不到骤菠,則在系統(tǒng)的include環(huán)境變量內(nèi)搜索。-
#include<>
搜索順序:在編譯器設(shè)置的include路徑內(nèi)搜索疤孕;
如果上一步找不到商乎,則在系統(tǒng)的include環(huán)境變量內(nèi)搜索。
-
#import指令
#import
與#include
的類似祭阀,都是把其后面的文件拷貝到該指令所在的地方#import
具有防止重復(fù)引用的功能鹉戚。在使用C語言時, 通常使用宏定義防止重復(fù)引用鲜戒。#import <>
用于包含系統(tǒng)文件,#import""
用于包含本項目中的文件。
@import ClassName 的使用
#import
導(dǎo)入程序所需的文件越多抹凳,所需的編譯時間越長遏餐,而有大量重復(fù)∮祝可創(chuàng)建.pch文件解決編譯時間長的問題失都。但是維護(hù).pch文件是很低效的。使用
@import
指令可使編譯器優(yōu)化預(yù)編譯頭文件和緩存編譯結(jié)果幸冻。同時粹庞,文件中不用再明確引用框架--編譯器會根據(jù)@import自動導(dǎo)入相應(yīng)框架。但該指令現(xiàn)階段還只能用于Apple提供的框架洽损,如果導(dǎo)入的是自己的類或框架還是需要
#import
庞溜。
@class ClassName 的使用
在頭文件中聲明某個類的對象時, 需要告訴編譯器此類存在, 但又不需要知道類的全部細(xì)節(jié)。此時可以使用
@class ClassName
告訴編譯器碑定。這叫做: “向前聲明”流码。(如果你寫的類繼承自某個超類, 則必須引入定義那個超類的頭文件)在實現(xiàn)文件中則需要引入類的頭文件, 因為在實現(xiàn)文件中需要使用類的細(xì)節(jié)。
注意: 將引入頭文件的時機(jī)盡量延后, 只有在確有需要時才引入, 這樣就可以減少類的使用者所引入頭文件數(shù)量不傅。以減少程序的編譯時間旅掂。
@class 和"循環(huán)引用"
類A與類B,如果在各自頭文件中引入對方的頭文件访娶,則會導(dǎo)致“循環(huán)引用”商虐。當(dāng)解析其中一個頭文件時,編譯器會發(fā)現(xiàn)它引入了另一個頭文件崖疤,而那個頭文件又回過頭來引用第一個頭文件秘车。
使用#import而非#include指令雖然不會導(dǎo)致死循環(huán),但卻意味著兩個類里有一個無法被正確編譯劫哼。
使用@class可以避免這種"循環(huán)引用"的問題
@class 和協(xié)議
如果要聲明某個類遵循一項協(xié)議, 那么該協(xié)議必須有完整定義, 且不能使用向前聲明叮趴。
向前聲明只能告訴編譯器有某個協(xié)議, 而此時編譯器卻要知道協(xié)議中定義的方法。
這種情況下权烧,盡量把“該類遵循某協(xié)議”的這條聲明移至“class-continuation分類”中眯亦。
"class-continuation分類"和普通的分類不同,它必須定義在其所接續(xù)的那個類的實現(xiàn)文件里般码。其重要之處在于妻率,這是唯一能聲明的實例變量的分類,而且此分類沒有特定的實現(xiàn)文件板祝,其中的方法都應(yīng)該定義在類的主實現(xiàn)文件里(.m文件中)宫静。
- 如果不行的話,就把協(xié)議單獨(dú)放到一個頭文件中,然后將其引入孤里。
要點(diǎn):
除非確有必要伏伯,否則不要引入頭文件。一般來說捌袜,應(yīng)在某個類的頭文件中使用向前聲明(就是@class obj)來提及別的類说搅,并在實現(xiàn)文件中引入那些類的頭文件。這樣可以盡量降低類之間的耦合(coupling) (在.h文件中使用@class obj來聲明琢蛤,在.m文件中再使用#import來引入頭文件)
有時無法使用向前聲明蜓堕,比如要聲明某個類遵循一項協(xié)議抛虏。這種情況下博其,盡量把“該類遵循某協(xié)議”的這條聲明移至“class-continuation分類”中。如果不行的話迂猴,就把協(xié)議單獨(dú)放到一個頭文件中慕淡,然后將其引入。