@class和#import的區別
使用@class不必知道這個類里到底有什么,只要知道有這樣一個類#import是把這個類里所有有的方法和屬性都導入了進來,非必要情況下,使用@class可以減少類的使用者所需引入頭文件的數量,也避免了引入根本用不到的內容,從而可以縮短編譯時間,所以我們將引入頭文件的時機盡量延后,只在確有需要時才引入。
頭文件的循環引用
我們常提到頭文件的循環引用,如果在A類里引入B類的頭文件,當解析A類頭文件時,編譯器會發現他引入了B類的頭文件,而B類頭文件又回過頭來應用A類頭文件,使用#import而非#include指令雖然不會導致死循環,但卻意味著這兩個類里有一個無法被正確編譯,@class也覺得了兩個類互相引用的問題。
協議單獨放在一個頭文件中
有時候,必須要在頭文件中引入其他頭文件,如果你寫的類繼承自某個超類,則必須引入定義那個超類的文件。同理,如果要聲明你寫的類遵從某個協議,那么該協議必須有完整定義,且不能使用向前聲明(@class),向前聲明只能告訴編譯器有某個協議,而此時編譯器卻要知道該協議中定義的方法,這樣#import是難免的,鑒于此,最好是把協議單獨放在一個頭文件里。要是把協議放到某個大文件里,那么只要引入協議,就必定會引入那個頭文件中的全部內容,如此一來,就會產生相互依賴問題,增加編譯器時間
委托協議(delegate protocol)
然而有些協議,例如“委托協議”,就不用單獨寫一個頭文件了,在那種情況下,協議只有與接受協議委托的類放在一起定義才有意義,此時最好能在實現文件中聲明此類實現了該協議,并把這段實現代碼放在“分類”。這樣的話,只要在實現文件中引入包含委托協議的頭文件即可,而不需要將其放在公共頭文件里。
要點
1、除非卻有必要,否則不要引入頭文件。一般來說,應在某個類的頭文件中使用先前聲明來提及別的類,并在實現文件中引入那些類的頭文件,這樣做可以盡量降低類之間的耦合
2、有時無法使用向前聲明,比如聲明某個類遵循一項協議。這種情況下,盡量把“該類遵循某協議”這條聲音移至分類里,如果不信的話,就把協議單獨放在一個頭文件中,然后將其引入。