1.import會包含這個類的所有資訊,包括實體變數和方法,而@class只是告訴編譯器,其後面宣告的名稱是類的名稱,至於這些類是如何定義的,暫時不用考慮,後面會再告訴你。
2.在標頭檔案中, 一般只需要知道被引用的類的名稱就可以了。 不需要知道其內部的實體變數和方法,所以在標頭檔案中一般使用@class來宣告這個名稱是類的名稱。 而在實現類裡面,因為會用到這個引用類的內部的實體變數和方法,所以需要使用#import來包含這個被引用類的標頭檔案。
4.如果有迴圈依賴關係,如:a–>b, b–>a這樣的相互依賴關係,如果使用#import來相互包含,那麼就會出現編譯錯誤,如果使用@class在兩個類的標頭檔案中相互宣告,則不會有編譯錯誤出現。
所以,一般來說,@class是放在inte***ce中的,只是為了在inte***ce中引用這個類,把這個類作為乙個型別來用的。 在實現這個介面的實現類中,如果需要引用這個類的實體變數或者方法之類的,還是需要import在@class中宣告的類進來.
舉個例子說明一下。
在classa.h中
#import classb.h 相當於#include整個.h標頭檔案。如果有很多.m檔案#import classa.h,那麼編譯的時候這些檔案也會#import classb.h增加了沒必要的#import,浪費編譯時間。在大型軟體中,減少.h檔案中的include是非常重要的。
如果只是 classb 那就沒有include classb.h。僅需要在需要用到classb的.m檔案中 #import classb.h
那麼什麼時候可以用呢?
如果classa.h中僅需要宣告乙個classb的指標,那麼就可以在classa.h中宣告
@classb
...classb *pointer;
假設,有兩個類:classa和classb,兩個之間相互使用到,即構成了circular dependency(迴圈依賴)。如果在標頭檔案裡面只用#import把對方的標頭檔案包含進來(構成circular inclusions,迴圈包含),則編譯器會報錯:
expected specifier-qualifier-list before 『classa』
或者expected specifier-qualifier-list before 『classb』
為了避免迴圈包含,在classa.h檔案裡面用@class classb把classb包含進來,同樣,在classb.h檔案裡面用@class classa把classa包含進來。@class指令只是告訴編譯器,這是個類,保留個空間來存放指標就可以了。
接下來,很可能在classa.m和classb.m中會有訪問包含進來物件的成員的情況,這時必須讓編譯器知道更多資訊,比如那個類有些什麼方法可以呼叫,就必須用#import,再次把用到的類包含進來,告訴編譯器所需要的額外資訊。
否則,編譯器會警告:
warning: receiver 『classa』 is a forward class and corresponding @inte***ce may not exist
還有另一種情況,使用有categories的類,要在.h標頭檔案裡用#import把categories包含進來。
總之,使用原則是:
標頭檔案裡面只#import超類 訊息檔案裡面#import需要發訊息過去的類 其他地方就用@class轉向宣告
import與 class的區別
1.import會包含這個類的所有資訊,包括實體變數和方法,而 class只是告訴編譯器,其後面宣告的名稱是類的名稱,至於這些類是如何定義的,暫時不用考慮,後面會再告訴你。2.在標頭檔案中,一般只需要知道被引用的類的名稱就可以了。不需要知道其內部的實體變數和方法,所以在標頭檔案中一般使用 class...
class與import的區別
2013 12 02 20 26 71人閱讀 收藏 舉報 objective c中,當乙個類使用到另乙個類時,並且在類的標頭檔案中需要建立被引用的指標時,如下面 a.h檔案 c import b.h inte ce a nsobject end c view plain copy print fon...
import與 class的區別
1.import會包含這個類的所有資訊,包括實體變數和方法,而 class只是告訴編譯器,其後面宣告的名稱是類的名稱,至於這些類是如何定義的,暫時不用考慮,後面會再告訴你。2.在標頭檔案中,一般只需要知道被引用的類的名稱就可以了。不需要知道其內部的實體變數和方法,所以在標頭檔案中一般使用 class...