鏈接器
從C代碼到可執(zhí)行文件經(jīng)歷的步驟是:
源代碼 > 預(yù)處理器 > 編譯器 > 匯編器 > 機(jī)器碼 > 鏈接器 > 可執(zhí)行文件
在最后一步需要把.o文件和C語(yǔ)言運(yùn)行庫(kù)鏈接起來(lái)茶鉴,這時(shí)候需要用到ld命令。源文件經(jīng)過(guò)一系列處理以后,會(huì)生成對(duì)應(yīng)的.obj文件,然后一個(gè)項(xiàng)目必然會(huì)有許多.obj文件,并且這些文件之間會(huì)有各種各樣的聯(lián)系届谈,例如函數(shù)調(diào)用。鏈接器做的事就是把這些目標(biāo)文件和所用的一些庫(kù)鏈接在一起形成一個(gè)完整的可執(zhí)行文件
通過(guò)這個(gè)流程你也應(yīng)該知道為什么在編譯的過(guò)程中沒(méi)事而在運(yùn)行的時(shí)候就會(huì)報(bào)錯(cuò)了. 那我們?yōu)槭裁匆O(shè)置Other Linker Flags呢 因?yàn)镺ther Linker Flags其實(shí)就是鏈接器工作時(shí)除了默認(rèn)參數(shù)外的其他參數(shù)。
閃退的原因
蘋果官方Q&A上有這么一段話:
The “selector not recognized” runtime exception occurs due to an issue between the implementation of standard UNIX static libraries, the linker and the dynamic nature of Objective-C. Objective-C does not define linker symbols for each function (or method, in Objective-C) - instead, linker symbols are only generated for each class. If you extend a pre-existing class with categories, the linker does not know to associate the object code of the core class implementation and the category implementation. This prevents objects created in the resulting application from responding to a selector that is defined in the category.
翻譯:運(yùn)行時(shí)的異常時(shí)由于靜態(tài)庫(kù),鏈接器,與OC語(yǔ)言的動(dòng)態(tài)的特性之間的問(wèn)題,OC語(yǔ)言并不是對(duì)每一個(gè)函數(shù)或者方法建立符號(hào)表,而只是對(duì)每一個(gè)類創(chuàng)建了符號(hào)表.如果一個(gè)類有了分類,那么鏈接器就不會(huì)將核心類與分類之間的代碼完成進(jìn)行合并,這就阻止了在最終的應(yīng)用程序中的可執(zhí)行文件缺失了分類中的代碼,這樣函數(shù)調(diào)用接失敗了.
我自己的理解:鏈接器在鏈接文件時(shí)航缀,只會(huì)生成類符號(hào)表,而在有分類時(shí)堰怨,因?yàn)轭惷嗤嬗瘢跃捅A袅艘粋€(gè),固而分類與核心類之間就沒(méi)有完成代碼合并备图,從而造成函數(shù)調(diào)用失敗灿巧。
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ù)文件的按需加載 .
別人建議ObjC與force_load搭配使用比較好.? 但是我自己目前用到ObjC的多一些门粪,這篇文章也是自己在看東西的時(shí)候突然想起,從而查的烹困。希望對(duì)看到的人有幫助玄妈。我也還需要再深入的學(xué)習(xí)。