一、#include與#import區(qū)別
1. #include <xxx.h>
2. #import <xxx.h>
用于對(duì)系統(tǒng)自帶的頭文件的引用香府,編譯器會(huì)在系統(tǒng)文件目錄下查找該文件董栽。
3. #include "xxx.h"
4. #import ?"xxx.h"
用戶自定義的文件用雙引號(hào)引用,引用時(shí)編譯器首先會(huì)在用戶目錄下查找企孩,然后去安裝目錄中查找锭碳,最后在系統(tǒng)文件目錄中查找。
區(qū)別:
#import和#include同樣可以將頭文件引入到我們需要的文件中勿璃,那么它們有什么區(qū)別呢?
當(dāng)我們?cè)诖a中對(duì)同一個(gè)文件進(jìn)行兩次#include的時(shí)候會(huì)報(bào)錯(cuò):因?yàn)?include相當(dāng)于拷貝頭文件中的內(nèi)容擒抛,所以會(huì)報(bào)重復(fù)定義的錯(cuò)誤。
例如: 有a.h补疑、b.h歧沪、c.h三個(gè)頭文件, ?b.h引用包含a.h, ? c.h中同時(shí)引用包含a.h和b.h:
如果使用#include來(lái)包含頭文件,不做重復(fù)引用處理情況下莲组,那么在c.h中相當(dāng)于包含了兩次a.h诊胞。這樣在編譯時(shí)就會(huì)引起不必要的錯(cuò)誤,這時(shí)就需要引入頭文件保護(hù)符才能避免c.h中重復(fù)引用包含兩次a.h锹杈。
頭文件保護(hù)參考C++頭文件保護(hù)撵孤,C語(yǔ)言預(yù)處理命令詳解
1#ifndef ?<標(biāo)識(shí)符>
2 ? ? ? ? ? ?#define ?<標(biāo)識(shí)符>
3 ? ? ? ? ? ?//真正的內(nèi)容,如函數(shù)聲明之類
4 #endif
如果使用#import來(lái)包含頭文件竭望,那么不需要做任何事情邪码,在c.h中就只會(huì)包含一次a.h,而不會(huì)引起任何錯(cuò)誤咬清。不管你對(duì)一個(gè)文件同時(shí)包含了多少次闭专,使用#import確定只會(huì)包含一次奴潘。所以它可以解決重復(fù)導(dǎo)入的問(wèn)題,它會(huì)做一次判斷影钉,如果已經(jīng)導(dǎo)入一次就不導(dǎo)入了画髓。 ? ? ? ? ? ? ? ? ?
實(shí)際上#import與#include功能基本相同,不過(guò)它避免了重復(fù)引用的問(wèn)題斧拍,我們?cè)谝梦募臅r(shí)候不用再去自己進(jìn)行重復(fù)引用處理雀扶。所以在OC中我們基本用的都是import。
注意:
在使用#include的時(shí)候要注意處理重復(fù)引用的問(wèn)題(這也是OC中#include與#import的區(qū)別 )
二肆汹、#import與@class區(qū)別
1.#import會(huì)將此類的所有文件全部導(dǎo)入,包括實(shí)例變量和方法予权。
@class只是告訴編譯器有這么一個(gè)類昂勉,引用類名,至于這些類是如何定義實(shí)現(xiàn)的不去考慮扫腺,一般用在.h文件的@interface之前岗照。
2.在頭文件中,@class一般用于頭文件中需要聲明該類的某個(gè)實(shí)例變量的時(shí)候笆环,此時(shí)只需要@class類名即可攒至,不需要知道其內(nèi)部的實(shí)體變量和方法。
而在.m文件里面躁劣,如果會(huì)用到這個(gè)引用類的內(nèi)部的實(shí)例變量和方法迫吐,就需要使用#import來(lái)包含這個(gè)被引用類的頭文件,這時(shí)候才包含了這個(gè)被引用的類的所有信息账忘。
3.為什么不直接在頭文件中直接#import呢?
如果有一個(gè)頭文件a.h志膀,在其他大量頭文件中都需要引用頭文件a.h,如果使用的是#import鳖擒,那么當(dāng)a.h中有了一點(diǎn)改動(dòng)時(shí)溉浙,其他包含a.h的頭文件都需要重新編譯,這將耗費(fèi)大量的時(shí)間蒋荚,降低了開(kāi)發(fā)效率戳稽。
而如果在需要的時(shí)候使用的是@class,當(dāng)a.h中有了一點(diǎn)改動(dòng)時(shí)期升,由于其他頭文件并沒(méi)有將a.h的內(nèi)容包含進(jìn)來(lái)惊奇,就不用重新編譯,提高了開(kāi)發(fā)效率吓妆。
還有一個(gè)用法會(huì)引起編譯錯(cuò)誤的就是在a.h中#import ‘’b.h‘’ 在b.h中#import ‘’a.h‘’那么在編譯的時(shí)候也會(huì)出現(xiàn)錯(cuò)誤赊时。
4.什么時(shí)候該用@class,什么時(shí)候需要用#import呢行拢?
(1)一般如果有繼承關(guān)系的用#import祖秒,如B是A的子類那么在B中聲明A?xí)r用#import。
(2)如果有循環(huán)依賴關(guān)系,如:A–>B, B–>A這樣的相互依賴關(guān)系竭缝,如果使用#import來(lái)相互包含房维,那么就會(huì)出現(xiàn)編譯錯(cuò)誤,如果使用@class在兩個(gè)類的頭文件中相互聲明抬纸,則不會(huì)有編譯錯(cuò)誤出現(xiàn). @class指令只是告訴編譯器咙俩,這是個(gè)類,保留個(gè)空間來(lái)存放指針就可以了湿故。
(3)還有就是自定義代理的時(shí)候阿趁,如果在頭文件中想聲明遵循代理,遵循協(xié)議的時(shí)候應(yīng)該用#import導(dǎo)入文件坛猪,不然的話會(huì)出錯(cuò)誤脖阵。(delegate還不太清楚,正在學(xué)習(xí)和實(shí)踐)
(4)使用有Category的類墅茉,要在.h頭文件里用#import把Category包含進(jìn)來(lái)命黔。
總結(jié):
1.能使用#import的地方就不要使用#inlclude
2.使用#import不管你對(duì)一個(gè)文件同時(shí)包含了多少次,最終只會(huì)包含一次
3.在頭文件中如果沒(méi)有用到包含類的實(shí)現(xiàn)方法就斤,只需要知道它是一個(gè)類時(shí)悍募,就應(yīng)該使用@class,而不是#import洋机。如果需要使用類的一些方法時(shí)坠宴,則需要使用#import。
4.能使用@class的地方就不要使用#import
本文章僅供學(xué)習(xí)參考槐秧,如有錯(cuò)誤之處歡迎指出和交流啄踊,謝謝!