
在Xcode -> Target -> BuildSettings的Search Paths中, 有兩個(gè)設(shè)置一個(gè)是 User Header Search Paths ,一個(gè)是 Header Search Paths.其實(shí)還有一個(gè)廢棄的Always Search User Paths。
Header Search Paths就是我們平時(shí)使用的, 設(shè)置頭文件搜索路徑的方法. 可以通過(guò)配置Header Search Paths 來(lái)引入頭文件, 從而可以使用該類.
Header Search Paths 與 User Header Search Paths 區(qū)別
Header Search Paths 管理導(dǎo)入的頭文件的路徑
Header Search Paths 和 User Header Search Paths 是具有同樣功能的,
區(qū)別在于 import 或者 include 頭文件時(shí),
Header Search Paths 會(huì)多一種方式.
當(dāng)import時(shí), 有兩種方式:
#import <SomeClass.h>
#import "SomeClass.h"
若在Header Search Paths中設(shè)置SomeClass的路徑后, 上面兩種方式都可以使用. 但是若在User Header Search Paths中設(shè)置后, #import <SomeClass.h> 就會(huì)編譯報(bào)錯(cuò)(include也是一樣).
具體一點(diǎn)的區(qū)別是,<>是從系統(tǒng)目錄空間 (對(duì)應(yīng)Header Search Paths)中搜索文件," " 是從用戶目錄空間(對(duì)應(yīng) User Header Search Paths)中搜索文件。如果你把路徑加到User Header Search Paths 中,而 <>無(wú)法從系統(tǒng)目錄空間中找到新加的路徑,從而報(bào)錯(cuò)。
Library search path
Library Search Paths 管理導(dǎo)入的*.a的路徑
Framewrok Search Path
Framework Search Paths 管理導(dǎo)入的*.framework的路徑
擴(kuò)展
1、其實(shí)還有另一個(gè)設(shè)置Always Search User Paths, 如果出現(xiàn)上面這樣的錯(cuò)誤, 這時(shí)把Always Search User Paths設(shè)置成 Yes,強(qiáng)制也import<> 也在User Header Search Paths搜索。 但是現(xiàn)在這個(gè)設(shè)置已經(jīng)廢棄了, 也不必過(guò)多探究了.
2、c / c++ 頭文件引用問(wèn)題
- include <> 引用編譯器的類庫(kù)路徑下的頭文件
- include “” 引用工程目錄的相對(duì)路徑的頭文件
include 是編譯指令,在編譯時(shí),編譯器會(huì)將相對(duì)路徑替換成絕對(duì)路徑,因此,頭文件絕對(duì)路徑:
絕對(duì)路徑 = 搜索路徑 + 相對(duì)路徑
- Xcode Build Settings 下 Search Paths設(shè)置搜索路徑,Header Search Paths:頭文件搜索路徑設(shè)置
$(SRCROOT) 和 $(PROJECT_DIR) 都指xxx.xcodeproj所在的父目錄
例如:引用工程testDemo/scr/test.h 頭文件,
注意:
- 如果在Header Search Paths中添加
$(SRCROOT)/scr,那么頭文件引用直接引用include "test.h" - 如果在Header Search Paths中添加
$(SRCROOT)/,那么頭文件引用直接引用include "scr/test.h"
一般工作中我們最好都使用相對(duì)路徑,這樣在共同開(kāi)發(fā)項(xiàng)目時(shí),防止發(fā)生路徑錯(cuò)誤問(wèn)題。
Library / Header Search Paths中寫(xiě)法:
$(SRCROOT) / 當(dāng)前工程名字 / 需要包含頭文件所在文件夾
3、(inherited)
參數(shù)會(huì)從PROJECT -> Build Settings -> Framework Search Paths`里面的路徑會(huì)被其繼承,沒(méi)有的話不會(huì)繼承。所以一個(gè)項(xiàng)目里面有多個(gè)target,使用到了同一個(gè)庫(kù)(Library或Framework)那么為了方便我們可以在target添加繼承參數(shù),并且PROJECT統(tǒng)一中添加庫(kù)的路徑。
4、non-recursive:默認(rèn)路徑設(shè)置,不遍歷該目錄。
recursive:遍歷該目錄,如果路徑的屬性為recursive,那么編譯的時(shí)候在找?guī)斓穆窂降臅r(shí)候,會(huì)遍歷該目錄下的所有子目錄的庫(kù)文件。
5、在Other Linker Flags中加入-ObjC或者-all_load或者-force_load
在ios開(kāi)發(fā)中,我們經(jīng)常會(huì)使用到第三方的一些靜態(tài)庫(kù),導(dǎo)入第三方類庫(kù)運(yùn)行程序后你會(huì)發(fā)現(xiàn),編譯時(shí)可以正常編譯但是運(yùn)行時(shí)會(huì)app會(huì)閃退,報(bào)出
selector not recognized的錯(cuò)誤
一般的第三方庫(kù)的開(kāi)發(fā)文檔中都會(huì)寫(xiě)出這種問(wèn)題的解決方法,在Other Linker Flags中加入-ObjC或者-all_load或者-force_load這樣的解決方法。
-ObjC
一般這個(gè)參數(shù)足夠解決前面提到的問(wèn)題,這個(gè)flag告訴鏈接器把庫(kù)中定義的Objective-C類和Category都加載進(jìn)來(lái)。這樣編譯之后的app會(huì)變大,因?yàn)榧虞d了很多不必要的文件而導(dǎo)致可執(zhí)行文件變大。但是如果靜態(tài)庫(kù)中有類和category的話只有加入這個(gè)flag才行,但是Objc也不是萬(wàn)能的,當(dāng)靜態(tài)庫(kù)中只有分類而沒(méi)有類的時(shí)候,Objc就失效了,這就需要使用-all_load或者-force_load了。-all_load
-all_load會(huì)強(qiáng)制鏈接器把目標(biāo)文件都加載進(jìn)來(lái),即使沒(méi)有objc代碼。但是這個(gè)參數(shù)也有一個(gè)弊端,那就是你使用了不止一個(gè)靜態(tài)庫(kù)文件,那么你很有可能會(huì)遇到ld: duplicate symbol錯(cuò)誤,因?yàn)椴煌膸?kù)文件里面可能會(huì)有相同的目標(biāo)文件 這里會(huì)有兩種方法解決 1:用命令行就行拆包. 2:就是用下面的這個(gè)參數(shù)-force_load
這個(gè)flag所做的事情跟-all_load其實(shí)是一樣的,只是-force_load需要指定要進(jìn)行全部加載的庫(kù)文件的路徑,這樣的話,你就只是完全加載了一個(gè)庫(kù)文件,不影響其余庫(kù)文件的按需加載 .
Xcode添加靜態(tài)庫(kù)以及編譯選項(xiàng)配置常見(jiàn)問(wèn)題
Xcode Search Paths相關(guān)配置