這是一個(gè)經(jīng)典的編譯報(bào)錯(cuò)問(wèn)題。相信大部分做iOS開(kāi)發(fā)的同學(xué)都遇到過(guò)。剛開(kāi)始遇到這個(gè)問(wèn)題時(shí),我會(huì)先嘗試去改改build settings里面的配置,或者寄希望于clean,實(shí)在搞不定的時(shí)候,就到網(wǎng)上去搜,搜到的解決方法確實(shí)很多,但是能夠解決問(wèn)題的卻很少,那是因?yàn)閷?dǎo)致該問(wèn)題的原因非常多,別人的方法不一定適用。后來(lái)認(rèn)識(shí)到這樣的解決問(wèn)題思路是錯(cuò)誤的。不應(yīng)該沒(méi)有目的地去嘗試,而應(yīng)該從關(guān)鍵的提示"symbols not found for architecture xxx"入手,分析出可能導(dǎo)致該問(wèn)題的原因,然后再有目的地去解決問(wèn)題,做到對(duì)癥下藥,這樣效率才會(huì)高。
"symbols not found for architecture xxx",意思是二進(jìn)制代碼中缺少xxx(如arm64,下文以arm64為例)架構(gòu)。編譯器的錯(cuò)誤提示肯定不會(huì)錯(cuò),那么為什么二進(jìn)制代碼中會(huì)缺少xxx呢?在解決問(wèn)題之前,不妨先分析一下。
項(xiàng)目中的二進(jìn)制代碼一般有兩個(gè)來(lái)源,一是項(xiàng)目build實(shí)時(shí)編譯出來(lái)的,二是引入的第三方庫(kù)(這里指已經(jīng)編譯成二進(jìn)制的第三方庫(kù),如.a或.framework文件)。對(duì)于第一種情況,毫無(wú)疑問(wèn),肯定是編譯時(shí)遇到某種問(wèn)題,導(dǎo)致編譯不成功,因而缺少arm64;對(duì)于第二種情況,因?yàn)槭且呀?jīng)編譯完成的,則有兩種可能。第一種可能是第三方庫(kù)本身就不包含arm64,第二種可能是,雖然第三方庫(kù)包含了arm64,但是編譯器卻沒(méi)有找到??偨Y(jié)一下,導(dǎo)致該問(wèn)題的本質(zhì)原因大概有三種:
- 確實(shí)不存在arm64
- 存在arm64但是找不到
- 因?yàn)槟撤N原因編譯不成功
抓住這三種本質(zhì)原因,是解決問(wèn)題的關(guān)鍵。下面逐一舉一些這幾種原因的例子和解決方案。
一、二進(jìn)制中確實(shí)不存在arm64
可以通過(guò)在終端中使用如下命令查看二進(jìn)制文件所包含的架構(gòu):
lipo -info xxx
如得到結(jié)果:
$ lipo -info Hyphenate.framework/Hyphenate
Architectures in the fat file: Hyphenate.framework/Hyphenate are: i386 x86_64
說(shuō)明該二進(jìn)制中確實(shí)不包含arm64,如果引入了這樣的二進(jìn)制文件,在運(yùn)行到真機(jī)時(shí)就會(huì)報(bào)錯(cuò)。
解決辦法:
找到包含arm64架構(gòu)的二進(jìn)制文件。
二、存在arm64但是找不到
1、第三方庫(kù)(.a或者.framework)沒(méi)有添加到Linked Framworks and Libraries
有時(shí)候引入第三方庫(kù)(主要是靜態(tài)庫(kù),如.a文件),是包含arm64架構(gòu)的,但是導(dǎo)入工程時(shí)方式不對(duì),使得.a文件沒(méi)有添加到Linked Framworks and Libraries列表中,這時(shí)候編譯器編譯時(shí)會(huì)找不到該.a文件,就會(huì)報(bào)錯(cuò)。

解決辦法:
將相應(yīng)的.a文件添加到Linked Framworks and Libraries中,就能解決問(wèn)題。
2、第三方庫(kù)(.a或者.framework)缺少系統(tǒng)依賴(lài)庫(kù)
有些第三方庫(kù),本身是依賴(lài)一些系統(tǒng)庫(kù)的,以Bugly為例,在官網(wǎng)上的集成文檔中,就會(huì)提醒用戶(hù)添加依賴(lài),需要添加的依賴(lài)有:

- SystemConfiguration.framework
- Security.framework
- libz.dylib 或 libz.tbd
- libc++.dylib 或 libc++.tbd
需要把這些依賴(lài)庫(kù)添加到Linked Framworks and Libraries。如果忘記添加這些,編譯器無(wú)法編譯庫(kù)文件,因此就會(huì)找不到,就會(huì)報(bào)錯(cuò)。
解決辦法:
將第三方庫(kù)的依賴(lài)系統(tǒng)庫(kù)添加到Linked Framworks and Libraries中
三、因?yàn)槟撤N原因編譯不成功
1、building settings中architecture不包含arm64
這種情況應(yīng)該大部分人都知道,你告訴編譯器不編譯arm64的架構(gòu),但是又要運(yùn)行在arm64架構(gòu)的手機(jī)上,當(dāng)然會(huì)報(bào)錯(cuò)啦。
解決辦法:
這種情況的解決辦法就是,在building settings中,architectures中添加arm64架構(gòu)。
2、.m文件沒(méi)有添加到build phase
有時(shí)候因?yàn)槟撤N原因,使得.m文件沒(méi)有添加到build phases, Compile Sources中,導(dǎo)致編譯失敗,也會(huì)報(bào)這種錯(cuò)誤。
解決辦法:
在build phases, Compile Sources中重新添加.m文件。
3、.m文件重復(fù)
項(xiàng)目中如果存在,兩個(gè)相同的.m文件,同樣會(huì)導(dǎo)致編譯失敗,也會(huì)報(bào)這種錯(cuò)誤。
解決辦法:
刪除重復(fù)的.m文件。
4、-ObjC配置
集成第三方庫(kù)時(shí),有時(shí)候需要做-ObjC配置,-ObjC的作用是將靜態(tài)庫(kù)中任何Objective-C代碼都鏈接到APP中,不配置的話,有時(shí)會(huì)使工程因文件找不到編譯失敗,會(huì)報(bào)這種錯(cuò)誤。
解決辦法:
Build Settings -> Linking -> Other Linker Flags ,添加上 -ObjC
5、集成含C++的庫(kù)
有些第三方庫(kù)包含C++代碼,用C++編譯器編譯得到的。如果引入了這種第三方庫(kù)(最典型的例子是百度地圖SDK),工程也需要使用C++編譯器編譯,否則會(huì)因編譯失敗報(bào)錯(cuò)。
解決辦法:
最簡(jiǎn)單的解決辦法是將工程中任意一個(gè).m文件改成.mm后綴。
6、bitcode問(wèn)題
有時(shí)候如果引入的第三方庫(kù)沒(méi)有使用bitcode,但是主工程中building settings的Enable Bitcode開(kāi)關(guān)打開(kāi)了,會(huì)引起編譯失敗,也會(huì)報(bào)"symbols not found for architecture xxx"錯(cuò)誤,當(dāng)然也會(huì)有bitcode關(guān)鍵字的錯(cuò)誤提示,比較明顯,也比較好解決。
解決辦法:
將主工程中Enable Bitcode開(kāi)關(guān)關(guān)閉。
目前只想到這些,但實(shí)際中肯定不止這些,后面遇到了再更新。只要把握造成該問(wèn)題的本質(zhì)原因,相信任何這種報(bào)錯(cuò)的問(wèn)題都能夠迎刃而解。