### iOS中如何處理SDK中重復(fù).o文件
-
在iOS開發(fā)中經(jīng)常會使用到第三方的SDK,有些SDK中有應(yīng)用的相同的類,如下圖所示:Demo工程中有A跟B兩個靜態(tài)庫,A跟B中又有相同的YTLog類
Demo工程目錄 -
該Demo在編譯時會報重復(fù).o文件錯誤,報錯如下圖所示:
Demo報錯
ld: warning: directory not found for option '-L/Users/z_yt/Desktop/ /Personal_file/5/TestDemo/StaticLibraryDemo/Library'
duplicate symbol OBJC_CLASS$_YTLog in:
/Users/z_yt/Library/Developer/Xcode/DerivedData/StaticLibraryDemoWorkspace-byqglqkcbrjzljfrqjqzzmgrbuvz/Build/Products/Debug-iphonesimulator/libLibraryB.a(YTLog.o)
/Users/z_yt/Library/Developer/Xcode/DerivedData/StaticLibraryDemoWorkspace-byqglqkcbrjzljfrqjqzzmgrbuvz/Build/Products/Debug-iphonesimulator/libLibraryA.a(YTLog.o)
duplicate symbol OBJC_METACLASS$_YTLog in:
/Users/z_yt/Library/Developer/Xcode/DerivedData/StaticLibraryDemoWorkspace-byqglqkcbrjzljfrqjqzzmgrbuvz/Build/Products/Debug-iphonesimulator/libLibraryB.a(YTLog.o)
/Users/z_yt/Library/Developer/Xcode/DerivedData/StaticLibraryDemoWorkspace-byqglqkcbrjzljfrqjqzzmgrbuvz/Build/Products/Debug-iphonesimulator/libLibraryA.a(YTLog.o)
ld: 2 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
由報錯的信息我們可以很明顯知道LibraryA跟LibraryB中有相同的類沖突,解決這種沖突的最好方法肯定是把其中一個SDK中相同的類修改名稱,但是實際開發(fā)中我們使用的SDK可能是沒有源碼,且也無法修改類名,這時可以通過刪除相同的.o文件來解決這個問題;
-
使用lipo命令可以查看到LibraryA的信息,命令為
lipo -info libLibraryA.a,
lipo查看SDK信息
由圖可以看出該SDK是no fat file,也就是只有x86_64模擬器版本,如果查看的結(jié)果為fat file,那么還需要做逐一解包的操作,操作命令為lipo LibraryA.a -thin armv7 -output userPath/xxx,userPath/xxx為你想存放的路徑; -
查看libLibraryA.a x86_64包中所包含的文件列表,其操作命令為
ar -t libLibraryA.a
libLibraryA.a x86_64包文件列表
由圖中我們可以看到其中就有YTLog.o文件
- 從libLibraryA.a x86_64包中解壓出所包含的文件,其操作命令為
ar xv libLibraryA.a
此處解壓出來的文件是在你的當(dāng)前路徑下(pwd可查看你的當(dāng)前路徑),而不是libLibraryA.a所在的路徑
libLibraryA.a x86_64解壓出objc file
刪除YTLog.o文件,
rm YTLog.o重新打包.a文件,其操作命令為
ar rcs libLibraryA.a *.o,執(zhí)行完該命令則會生成一個新的libLibraryA庫如果你的庫為fat file的話則每個平臺的包都要執(zhí)行上面6-8的動作,然后再執(zhí)行合并各平臺包的操作
lipo -create libLibraryA-armv7.a libLibraryA-armv7s.a libLibraryA-i386.a -output libLibraryA.a把重新打包出來的庫導(dǎo)入工程中就可以正常運行起來了;
注意事項
-
Demo工程中可能有人能夠成功run起來而不用刪除重復(fù)的.o文件,這是因為沒有把兩個sdk中的所有文件導(dǎo)入工程中,要把sdk的所有文件導(dǎo)入工程中要在工程的build Settings中設(shè)置Other Linker Flags,如圖所示
設(shè)置Other Linker Flags Other Linker Flags幾個參數(shù) -ObjC -all_load -force_load的意義
-ObjC:加了這個參數(shù)后,編譯器會把靜態(tài)庫中所有的OC類和分類都導(dǎo)入到最后的可執(zhí)行文件中。注意該參數(shù)的O是大寫的。
-all_load:編譯器會把所有找到的目標(biāo)文件都加載到可執(zhí)行文件中。該參數(shù)的出現(xiàn)的是為解決靜態(tài)庫中只有Category時,-Objc參數(shù)失效的bug。但正常情況下不要輕易使用該參數(shù)。要解決-Objc失效的問題也可以使用下面的參數(shù)-force_load。
-force_load:所做的事情跟-all_load是一樣的,但是-force_load要指定需要加載的靜態(tài)庫的文件路徑,這中設(shè)置就可以僅僅完全加載一個庫文件,而不影響其他靜態(tài)庫。
- 該方法只能刪除名稱相同且實現(xiàn)相同的類,加入該類僅僅是類名相同,但是實現(xiàn)不一樣,這樣刪除任意一個類都會導(dǎo)致編譯失??;





