黑馬程式設計師 import和class的區別

2021-06-23 07:34:39 字數 1682 閱讀 9893

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轉向宣告

黑馬程式設計師

asp.net android ios開發 net培訓 期待與您交流!map hashtable 底層是雜湊表資料結構,不可以存入null鍵和null值。該執行緒是同步的,jdk1.0出現,效率低。hashmap 底層是雜湊表資料結構,允許使用null鍵和null值。該集合執行緒是不同步的,將has...

黑馬程式設計師

1.了解反射 反射 就是通過class檔案物件,去使用該檔案中的成員變數,構造方法,成員方法。person p new person p.使用 要想這樣使用,首先你必須得到class檔案物件,其實也就是得到class類的物件。2.反射中的類 class類 成員變數 field類 構造方法 const...

黑馬程式設計師

黑馬程式設計師 j a基礎學習筆記2 一 筆記內容概述 關鍵字 識別符號 注釋 注釋的應用 常量 進製的由來 進製轉換 負數的進製 變數的介紹 變數的基本演示 型別提公升 強制轉換 字元型別運算過程 型別運算細節 算術運算子 賦值運算子。二 常用內容介紹 1.注釋內容不占用記憶體,即使新增再多的注釋...