Xcode中other linker flags 的作用

使用場景

<p> 在ios開發中,我們經常會使用到第三方的一些靜態庫,導入第三方類庫運行程序后你會發現,編譯時可以正常編譯但是運行時會app會閃退,報出selector not recognized的錯誤。一般的第三方庫的開發文檔中都會寫出這種問題的解決方法,如在Other Linker Flags中加入-ObjC或者-all_load或者-force_load這樣的解決方法。為什要這要做呢?報錯為什么編譯的時候有問題呢,首先我們先引入一個鏈接器的概念.</p>

鏈接器

<p>
還記得我們在學習C程序的時候,從C代碼到可執行文件經歷的步驟是:
</p>

源代碼 > 預處理器 > 編譯器 > 匯編器 > 機器碼 > 鏈接器 > 可執行文件

在最后一步需要把.o文件和C語言運行庫鏈接起來,這時候需要用到ld命令。源文件經過一系列處理以后,會生成對應的.obj文件,然后一個項目必然會有許多.obj文件,并且這些文件之間會有各種各樣的聯系,例如函數調用。鏈接器做的事就是把這些目標文件和所用的一些庫鏈接在一起形成一個完整的可執行文件
通過這個流程你也應該知道為什么在編譯的過程中沒事而在運行的時候就會報錯了. 那我們為什么要設置Other Linker Flags呢 因為Other Linker Flags其實就是鏈接器工作時除了默認參數外的其他參數。

閃退的原因

蘋果官方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.

翻譯:運行時的異常時由于靜態庫,鏈接器,與OC語言的動態的特性之間的問題,OC語言并不是對每一個函數或者方法建立符號表,而只是對每一個類創建了符號表.如果一個類有了分類,那么鏈接器就不會將核心類與分類之間的代碼完成進行合并,這就阻止了在最終的應用程序中的可執行文件缺失了分類中的代碼,這樣函數調用接失敗了.

other linker flags參數的作用

在前面我們說如果出現問題要在Other Linker Flags中加入-ObjC或者-all_load或者-force_load,我們為什么要加入這樣的參數呢,他們究竟做了什么事呢?下面就是對這個三個參數的一個講解.

ObjC

一般這個參數足夠解決前面提到的問題,這個flag告訴鏈接器把庫中定義的Objective-C類和Category都加載進來。這樣編譯之后的app會變大,因為加載了很多不必要的文件而導致可執行文件變大。但是如果靜態庫中有類和category的話只有加入這個flag才行,但是Objc也不是萬能的,當靜態庫中只有分類而沒有類的時候,Objc就失效了,這就需要使用-all_load或者-force_load了。

-all_load

-all_load會強制鏈接器把目標文件都加載進來,即使沒有objc代碼。但是這個參數也有一個弊端,那就是你使用了不止一個靜態庫文件,那么你很有可能會遇到ld: duplicate symbol錯誤,因為不同的庫文件里面可能會有相同的目標文件 這里會有兩種方法解決 1:用命令行就行拆包. 2:就是用下面的這個參數

-force_load

這個flag所做的事情跟-all_load其實是一樣的,只是-force_load需要指定要進行全部加載的庫文件的路徑,這樣的話,你就只是完全加載了一個庫文件,不影響其余庫文件的按需加載 .

總結

個人建議ObjC與force_load搭配使用比較好.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容