天天看點

-ObjC引起的duplicate symbol _OBJC_IVAR

ld: 205 duplicate symbols for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
           

通過去掉other linker flags的-ObjC解決。

-ObjC引起的duplicate symbol _OBJC_IVAR

為什麼不加-ObjC時,CorePlot會崩,出現“selector not recognized”情況?

“-Objc這個标志,和Objective-C的一個重要特性:類别(category)有關。根據這裡的解釋,Unix的标準靜态庫實作和Objective-C的動态特性之間有一些沖突:Objective-C沒有為每個函數(或者方法)定義連結符号,它隻為每個類建立連結符号。這樣當在一個靜态庫中使用類别來擴充已有類的時候,連結器不知道如何把類原有的方法和類别中的方法整合起來,就會導緻你調用類别中的方法時,出現"selector not recognized",也就是找不到方法定義的錯誤。為了解決這個問題,引入了-ObjC标志,它的作用就是将靜态庫中所有的和對象相關的檔案都加載進來。”

簡單的說就是,在沒有添加-ObjC的情況下,某些靜态庫中的Category函數是沒有被識别的,調用該函數時沒找到這個函數的指針,就報錯了。

編譯過程:

從C代碼到可執行檔案經曆的步驟是:源代碼 > 預處理器 > 編譯器 > 彙編器 > 機器碼 > 連結器 > 可執行檔案

在最後一步需要把.o檔案和C語言運作庫連結起來,這時候需要用到ld指令。源檔案經過一系列處理以後,會生成對應的.obj檔案,然後一個項目必然會有許多.obj檔案,并且這些檔案之間會有各種各樣的聯系,例如函數調用。連結器做的事就是把這些目标檔案和所用的一些庫連結在一起形成一個完整的可執行檔案。Other linker flags設定的值實際上就是ld指令執行時後面所加的參數

下面逐個介紹3個常用參數:

-ObjC:加了這個參數後,連結器就會把靜态庫中所有的Objective-C類和分類都加載到最後的可執行檔案中

-all_load:會讓連結器把所有找到的目标檔案都加載到可執行檔案中,但是千萬不要随便使用這個參數!假如你使用了不止一個靜态庫檔案,然後又使用了這個參數,那麼你很有可能會遇到ld: duplicate symbol錯誤,因為不同的庫檔案裡面可能會有相同的目标檔案,是以建議在遇到-ObjC失效的情況下使用-force_load參數。

-force_load:所做的事情跟-all_load其實是一樣的,但是-force_load需要指定要進行全部加載的庫檔案的路徑,這樣的話,你就隻是完全加載了一個庫檔案,不影響其餘庫檔案的按需加載

繼續閱讀