該篇文章是我自己從我的新浪博客上摘抄過來的, 原文鏈接為: http://blog.sina.com.cn/s/blog_dcc636350102wat5.html
在iOS開發中, 難免會集成別人的三方類庫, 當集成的三方類庫過多時, 難免會出現某些庫同時使用了同樣的函數庫,導致link的時候報錯提示duplicate symbol。詳情見圖:
這樣的報錯讓我們覺得很麻煩, 這樣的文件重復錯誤, 不是由自己的程序中的代碼造成的, 而是別人的三方類庫, 也就是說,這種情況下, 我們沒有辦法通過修改自己的代碼而使問題得到解決。 我們就只能要求第三方(函數庫的提供方)提供源碼, 然后自己修改,或者是讓三方代碼提供者自己修改了之后給我們, 不管怎樣, 多少會覺得有點無理要求了。 那么我們就只能想想辦法自己解決了, 也就是修改.a文件或者framework中的二進制文件。
修改這樣的錯誤, 我們需要用到lipo 和 ar 工具。 不知道用法的可以網上稍微搜索一下。
那么我們現在就來修改一下吧。
一、找到重復的庫文件(兩個庫文件重復找其中之一即可, 三個庫文件, 找到重復文件的其中兩個, .....以此類推),你可以直接在該項目下的文件夾進行操作(不建議, 容易使程序出問題),你也復制這些庫文件到其它文件夾進行操作。我們這里復制到其它文件夾下進行操作。需要復制的文件見圖:
二、打開終端, 并cd 到文件夾下, 使用 lipo -info ASIAIDCardReader (ASIAIDCardReader替換為自己的文件名稱)查看該文件下的架構信息, 留待后用
三、我們可以看最后一行信息, 此處 Architecturesin the fat file, 說明此處是一個fat文件, 我們需要對該文件先進行瘦身, 即分離出armv7、arm64和armv7s文件。
使用命令 lipo ASIAIDCardReader -thin armv7-output ASIAIDCardReader.armv7 (ASIAIDCardReader.armv7 中ASIAIDCardReader 可替換為自己的文件名稱,且該名稱可以自定義), 使用類似的方法(只需要將 .armv7修改為相應的架構信息后綴即可),分離出其它的文件
四、文件已經分離出來, 下面我們使用ar 工具, 查看各文件下的二進制文件(.o文件)。 此處我們可以使用 ar -t在終端中查看所有的.o文件
也可以使用 ar -x將所有.o文件分離到指定的目錄文件夾。
根據我們最開始的錯誤定位,從上面我們都能輕易找到重復的文件 AsyncSocket.o和AsyncSocket相關的文件,接下來就是對分離出來的文件進行修改了。
五、使用命令 ar -d -sv ASIAIDCardReader.armv7s AsyncSocket.o,即刪除ASIAIDCardReader.armv7s下的 AsyncSocket.o二進制文件(你只需要替換成你自己的庫文件名稱和.o文件即可),同樣對分離出來的.arm64、.armv7s進行同樣的操作。
六、文件修改好了, 接下來我們需要把修改好的文件,全部再組合成我們原來的framework下的fat文件。使用命令
lipo-create -output ASIAIDCardReaderASIAIDCardReader.armv7sASIAIDCardReader.arm64 ASIAIDCardReader.armv7(此處需要把所有分離出來的文件都加上)
為了使我們確認還原了ASIAIDCardReader文件, 我們將復制文件夾下的該文件刪除, 再進行操作。使用命令之后, 我們就能看到生成了一個新的 ASIAIDCardReader文件, 這就是我們修改之后,符合我們需求的文件了。
七、將修改好的文件, 拖拽到原文件夾下,替換原文件即可。
注:其它由重復的framework, 按照以上方法重復一遍即可。