靜態(tài)庫申钩、Framework 的鏈接與合并

常見的庫文件格式

.a : 靜態(tài)庫
.dylib : 傳統(tǒng)意義動(dòng)態(tài)庫
.framework : 可動(dòng)可靜
.xcframework: 針對不同架構(gòu)的搞一起次绘。

xcframework,18年蘋果出的新的庫的格式瘪阁,我們平常開發(fā)中對胖庫各種架構(gòu)都支持的sdk ,上線的時(shí)候需要把比如模擬器的架構(gòu)剔除邮偎,為了節(jié)省空間管跺,可是當(dāng)想用模擬器運(yùn)行的時(shí)候又會(huì)發(fā)現(xiàn)此架構(gòu)被剔除了,所以這種庫的出現(xiàn)會(huì)省去此操作禾进,想要鏈接什么架構(gòu)就鏈接什么架構(gòu)豁跑。

這篇文章主要介紹 .a 和.framework

什么時(shí)候會(huì)用到庫

1、某些代碼需要給別人使用泻云,但是我們不希望別人看到源碼艇拍,就需要以庫的形式進(jìn)行封裝狐蜕,只暴露出頭文件。
2卸夕、對于某些不會(huì)進(jìn)行大改動(dòng)的代碼层释,我們想減少編譯時(shí)間,就可以把它打包成庫快集,因?yàn)閹焓且呀?jīng)編譯好的二進(jìn)制贡羔,編譯的時(shí)候只需要link一下,不會(huì)浪費(fèi)編譯時(shí)間个初。

操作準(zhǔn)備

先看一份代碼

#import <Foundation/Foundation.h>
#import <AFNetworking.h>

int main(){
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    NSLog(@"testApp----%@", manager);
    return 0;
}

  • 上面代碼就是一個(gè)簡單的test.m文件乖寒。
  • 可以看到 此代碼引用了 AFNetworking 并用到了里面的一個(gè)方法,這樣就構(gòu)成了一個(gè)場景院溺,我們的主工程用到了一個(gè)第三方庫楣嘁。

在看一下這個(gè)目錄


截屏2021-03-06 上午11.28.25.png
  • 這里可以看到我們引用的是一個(gè)AFNetworking的靜態(tài)庫代碼(因?yàn)槲覀兛吹搅?a)
  • 還有它的頭文件

file 命令去查看一下它具體的格式


截屏2021-03-06 上午11.33.57.png

lipo -info 可以去查看它支持的一個(gè)架構(gòu)


截屏2021-03-06 上午11.36.26.png

此時(shí) 就給我們鏈接一個(gè)靜態(tài)庫需要的所有信息。

那這個(gè)靜態(tài)庫.a 到底是什么覆获?是什么格式马澈?
上面 通過 file 命令我們知道它是一個(gè) archive 文檔格式的,
我們還知道它是一個(gè).o 文件的合集 那么我們可以通過 ar命令 來查看一下


截屏2021-03-06 上午11.48.11.png
  • 由此 可以驗(yàn)證出 .a 它就是一個(gè).o文件的合集

正式鏈接

上邊我們已經(jīng)準(zhǔn)備好調(diào)節(jié)弄息,下面我們就正式的將我們的.m與AFN進(jìn)行一個(gè)鏈接

  • 首先我們知道 編譯的一個(gè)過程是將.m 生成目標(biāo)文件.o 之后再進(jìn)行一個(gè)鏈接.最后生成可執(zhí)行文件痊班,或者 動(dòng)態(tài)庫。

1摹量、將test .m文件編譯為目標(biāo)文件
這里就需要借助我們平常熟悉的東西 Clang 大家都知道锚赤,clang是前端編譯器。那么我們看一下它的自描述


截屏2021-03-06 上午11.57.21.png
  • clang 是一個(gè) c 消返、c++ 和 oc 的編譯器
  • clang是一個(gè)C, c++和Objective-C編譯器郁岩,包含了 預(yù)
    處理、解析睦尽、優(yōu)化器净、代碼生成、匯編和鏈接当凡。
    根據(jù)傳入的高級模式設(shè)置山害,Clang將停止
    在做一個(gè)完整的鏈接之前
  • clang可執(zhí)行文件實(shí)際上是一個(gè)小的驅(qū)動(dòng)程序,它控制其他程序的整體執(zhí)行
    諸如編譯器沿量、匯編器和鏈接器等工具浪慌。通常,您不需要與
    驅(qū)動(dòng)程序朴则,但您可以使用它來運(yùn)行其他工具权纤。

2.開始編譯為.o

clang -x objective-c \
-target x86_64-apple-macos11.0\
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-I ./AFNetworking \
-c test.m -o test.o
  • clang -x :來指定編譯的語言.
  • -target : 指定編譯的架構(gòu)
  • -fobjc-arc : 指定為 arc環(huán)境
  • -isysroot : 這就是用到的系統(tǒng)庫所在的位置 (例如我們.m 里面引用了<Foundation/Foundation.h>)
  • -I :指定里面引用的第三方庫頭文件的路徑 header serach path
  • -c :輸出
  • \ 換行輸入 為了好看

通過上面一系列操作 遍輸出了.o文件


截屏2021-03-06 下午12.53.03.png
  • 在上篇文章我們有講過.o 里邊有重定位符號表,重定位符號里保存的是 當(dāng)前用到的符號. 那它的作用是什么?其實(shí)就是當(dāng)我們進(jìn)行鏈接的時(shí)候汹想,通過這個(gè)重定位符號表再次重定位外邓,生成具體的一個(gè)符號信息。
  • 這也就是為什么我們生成目標(biāo)文件只需要一個(gè)頭文件的地址就可以了古掏,因?yàn)樵偕赡繕?biāo)文件的時(shí)候坐榆,只需要告訴clang 哪個(gè)地方需要進(jìn)行重定位就好了。
  1. 進(jìn)行鏈接 靜態(tài)庫 生成可執(zhí)行文件
    上面我們已經(jīng)完成了目標(biāo)文件的生成冗茸,下面我們通過連接器生成可執(zhí)行文件席镀,同樣的我們知道我們的clang也是包含我們鏈接器的一個(gè)接口的。
$ clang -target x86_64-apple-macos11.0 \
-fobjc-arc \ 
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-L./AFNetworking \
-lAFNetworking \
test.o -o test
ld: in ./AFNetworking/libAFNetworking.a(AFHTTPSessionManager.o), building for macOS, but linking in object file built for iOS Simulator, for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)


  • -target :指定架構(gòu)
  • -fobjc-arc:指定 為arc
  • -isysroot : 系統(tǒng)庫所在的位置 如NSLog
  • -L :第三方靜態(tài)庫的位置(這里是libAFNetworking.a的地址夏漱,向我們xcode Library Search Paths)

鏈接的過程就需要把重定位符號表的符號進(jìn)行重定位豪诲,也就是說需要符號的真實(shí)的地址,向我們用到的AFHTTPSessionManager 它真實(shí)的地址在哪? 是不是保存在靜態(tài)庫.a 里面的.o文件里去了挂绰,也就是在.a的重定位符號表里屎篱, 我們生成的.o也有重定位符號表,當(dāng)生成可執(zhí)行文件的時(shí)候會(huì)將其融合生成一個(gè)完整的符號表葵蒂。因?yàn)樵诳蓤?zhí)行文件中只有一個(gè)符號表交播。

  • -l:上面我們告訴了連接器我的靜態(tài)庫放在哪里那接下來就需要告訴它我連接哪個(gè)庫文件(注意:這里說的是庫文件并沒有說靜態(tài)庫) 這里是提供了一個(gè) -l 參數(shù) 這里我們寫-lAFNetworking

那這里為什么這么寫-lAFNetworking ?因?yàn)樗怯幸粋€(gè)查找規(guī)則的践付,它會(huì)先查找lib+<library_name>的動(dòng)態(tài)庫秦士,找不到再去找lib+<library_name>的靜態(tài)庫 ,在找不到就會(huì)報(bào)錯(cuò)永高。

  • test.o -o test : 輸入為可執(zhí)行文件隧土。

上面為啥報(bào)錯(cuò) 因?yàn)槭茿FNetworking 架構(gòu)的問題,它是模擬器架構(gòu)命爬,我們這是電腦環(huán)境曹傀。

重要

通過上面的操作我們知道了:鏈接成功一個(gè)庫的三要素:
1、-l<directory> (大i)指定目錄尋找頭文件

xcode: Header Search Paths

2饲宛、-L<dir> 指定庫文件路徑

xcode: :Library Search Paths

3皆愉、-l<library_name>(小L)指定鏈接庫文件名稱(.a.dylib庫文件)

xcode: Other link flags 配置的 如-lAFNetworking

靜態(tài)庫的合并

我們知道靜態(tài)庫是.o文件的合集,那么我們是不是可以將多個(gè).a文件合并為一個(gè).a當(dāng)然是可以的
看一下

可以通過 ar命令 來進(jìn)行 操作

ar

屏幕快照 2021-03-10 下午8.35.26.png
  • ar——?jiǎng)?chuàng)建和維護(hù)library 文檔格式艇抠。
  • ar實(shí)用程序創(chuàng)建并維護(hù)合并到存檔中的文件組幕庐。一旦創(chuàng)建了存檔,就可以添加和刪除新文件
    可以提取练链、刪除或替換現(xiàn)有文件翔脱。

隨意找兩個(gè).a 我們進(jìn)行一個(gè)合并 下面我就搞倆.a


屏幕快照 2021-03-10 下午8.48.25.png

首先查看一下 下面兩個(gè).a 中的內(nèi)容


屏幕快照 2021-03-10 下午8.52.15.png
  • 由此可見的確是.o的一個(gè)合集

下面我們將兩個(gè) .a進(jìn)行一個(gè)合并 這時(shí)我們就又用到一個(gè)命令 libtool
同樣的看一下自描述


屏幕快照 2021-03-10 下午9.04.55.png
  • libtool-創(chuàng)建庫
    ranlib-添加或更新存檔庫的目錄

  • libtool命令獲取指定的輸入對象文件奴拦,并創(chuàng)建一個(gè)庫媒鼓,用于鏈接編輯器ld(1)。庫的名稱由output指定(指向-o標(biāo)志的參數(shù))。輸入對象文件可以是包含對象文件(“通用”文件绿鸣、歸檔文件疚沐、對象文件)的任何正確格式。Libtool不會(huì)將任何非對象輸入文件放入輸出庫(與ranlib不同潮模,ranlib允許在其操作的歸檔文件中進(jìn)行此操作)亮蛔。
    當(dāng)從相同CPU類型和不同CPU子類型的對象生成“通用”文件時(shí),libtool和ranlib最多為每個(gè)CPU類型創(chuàng)建一個(gè)庫擎厢,而不是在通用文件中為每個(gè)CPU類型和CPU子類型的唯一配對創(chuàng)建一個(gè)單獨(dú)的庫究流。因此,每個(gè)庫的結(jié)果CPU子類型是該CPU類型的\u ALL CPU子類型动遭。此策略強(qiáng)烈鼓勵(lì)庫的實(shí)現(xiàn)者創(chuàng)建一個(gè)庫芬探,該庫選擇在運(yùn)行時(shí)而不是在鏈接時(shí)運(yùn)行的最佳代碼。

  • Libtool可以創(chuàng)建動(dòng)態(tài)鏈接的共享庫(使用動(dòng)態(tài))厘惦,也可以創(chuàng)建靜態(tài)鏈接(存檔)庫(使用-static)偷仿。

好了知道大概描述了我們開始實(shí)操

?  靜態(tài)庫合并 libtool \
-static \   
-o \     
libABTest.a \
libA_LibTest.a \
libB_LibTest.a

查看合并的 libABTest.a 的.o合集

?  靜態(tài)庫合并 ar -t libABTest.a 
__.SYMDEF SORTED
A_LibTest.o
A_Manager.o
A_Tool.o
B_Manager.o
B_LibTest.o
B_Tool.o
  • 此時(shí)可以看到 兩個(gè)庫的.o文件 被合并在了一起。
  • 此時(shí)庫.o已經(jīng)合并 那是不是就是一個(gè)處理頭文件的問題了宵蕉?

Framework

Mac OS/iOS平臺(tái)還可以使用Framework. Framework實(shí)際上是一種打包方式酝静,將庫的二進(jìn)制文件,頭文件和有關(guān)的資源打包在一起羡玛,方便管理和分發(fā)别智。

Framework 和系統(tǒng)的UIKit.Framework 還是有很大的區(qū)別。系統(tǒng)的Framework 不需要拷貝到目標(biāo)程序中稼稿,我們自己做出來的Framework 哪怕是動(dòng)態(tài)的亿遂,最后也還是要拷貝到App中(App 和 Extension的Bundle 是共享的),因此蘋果又把這種Framework稱為 Embedded Framework.

Embedded Framework:
開發(fā)中使用的動(dòng)態(tài)庫會(huì)被放入到ipa下的framework目錄下渺杉,基于沙盒運(yùn)行蛇数。
不同的App使用相同的動(dòng)態(tài)庫,并不會(huì)只在系統(tǒng)中存在一份是越。而是會(huì)在多 個(gè)App中各自打包耳舅、簽名、加載一份倚评。

屏幕快照 2021-03-10 下午9.45.32.png
  • 從上面的描述想必大家也 明白了Framework其實(shí)就是 即將庫本身的格式還有頭文件 簽名 以資源文件 放在了一起浦徊。

手動(dòng)創(chuàng)建Framework

先看一下 AFNetworking的franmework的目錄


屏幕快照 2021-03-10 下午10.17.47.png

我們按照它的格式手動(dòng)來創(chuàng)建一個(gè)

1、我們以 A_libTest 靜態(tài)庫為例 在我們項(xiàng)目中 來鏈接它 并執(zhí)行天梧。


屏幕快照 2021-03-10 下午10.05.37.png

2盔性、新建文件夾并改為A_LibTest .framework 將上面編譯出來的libA_LibTest.a 放進(jìn) A_LibTest .framework 中 并新建立 heards 文件夾 將頭文件 扔進(jìn)去,按照Framework的格式我們將lib 還有.a 都去掉


屏幕快照 2021-03-10 下午10.23.01.png
屏幕快照 2021-03-10 下午10.21.33.png

屏幕快照 2021-03-10 下午10.33.57.png
  • 通過??步驟 我們已經(jīng)創(chuàng)建好了一個(gè)Framework 下面我們進(jìn)行連接看一下

看一下準(zhǔn)備的test.m 它引入了 Framework中的一個(gè)頭文件A_Manager.h 并且main函數(shù)里使用了 此類的一個(gè)方法 -(void)A_Manager_TestFunction

屏幕快照 2021-03-10 下午10.32.46.png

屏幕快照 2021-03-10 下午10.33.14.png

下面我們來進(jìn)行編譯一下

clang -x objective-c \
-target x86_64-apple-macos10.13 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk \
-I./Frameworks/A_LibTest.framework/Headers \
-c test.m -o test.o
屏幕快照 2021-03-10 下午10.44.18.png
  • 可以看到被我們編譯為了.o

下面開始 鏈接 按照我們上面講的三要素 1 呢岗、指定目錄尋找頭文件(-大i)2冕香、指定庫文件路徑 -L 3蛹尝、指定鏈接庫文件名稱 那么那是 .a 或者是 .dylib 下面看一下Framework的手動(dòng)鏈接

clang -target x86_64-apple-macos10.13 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk \
-F./Frameworks \
-framework A_libTest \
test.o -o test
  • 首先 可以看到 前面命令是一樣的
  • -F 指定Framework 所在的目錄 當(dāng)前我們的在./Frameworks
  • -framework 指定要鏈接哪個(gè)Framework 當(dāng)前我們鏈接的是 A_libTest


    屏幕快照 2021-03-10 下午11.15.37.png
  • 可以看到我們已經(jīng)鏈接成功并成功的輸出了可執(zhí)行文件

下面我們運(yùn)行一下看能否調(diào)用成功

屏幕快照 2021-03-10 下午11.20.04.png

重要

通過上面的操作我們知道了:鏈接成功一個(gè)Framework:
1、-l<directory> (大i)指定目錄尋找頭文件

xcode: Header Search Paths
2悉尾、-F<directory> 指定目錄尋找framewok

xcode: :framework search path
3突那、-framework<framework_name> 指定鏈接的framework名稱

xcode: Other link flags 配置的 如-framework AFNetworking

通過shell 腳本來 操作

環(huán)境準(zhǔn)備
屏幕快照 2021-03-18 下午9.51.56.png
屏幕快照 2021-03-18 下午9.52.30.png
屏幕快照 2021-03-18 下午9.53.55.png

開始編寫腳本build.sh

首先 將 test.m 編譯成中間代碼

echo "-----開始編譯test.m"
clang -x objective-c \
-target x86_64-apple-macos10.13 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk \
-I./StaticLibrary \
-c test.m -o test.o

然后進(jìn)入到StaticLibrary 中將 A_Manager 編譯成中間代碼

echo "-----開始進(jìn)入StaticLibrary目錄"
pushd ./StaticLibrary
echo "-----開始編譯A_Manager.m 為目標(biāo)文件"
clang -x objective-c \
-target x86_64-apple-macos10.13 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk \
-I./Frameworks/A_LibTest.framework/Headers \
-c A_Manager.m -o A_Manager.o

將 A_Manager.o 打包為.a

echo "-----開始將目標(biāo)文件打包為 libA_Manager.a"
ar -rc libA_Manager.a A_Manager.o

退出當(dāng)前目錄 將test.o 鏈接 libA_Manager.a 并生成可執(zhí)行文件EXE

echo "-----開始退出StaticLibrary目錄"
popd
echo "-----將test.o 鏈接 libA_Manager.a 并生成可執(zhí)行文件EXE"
clang -target x86_64-apple-macos10.13 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk \
-L./StaticLibrary \
-lA_Manager \
test.o -o test

開始運(yùn)行./build.sh


屏幕快照 2021-03-18 下午10.11.10.png
屏幕快照 2021-03-18 下午10.12.34.png

此時(shí)我們可以看到 每一步的操作用腳本來實(shí)現(xiàn)是如此簡單

如遇到:zsh: permission denied: ./build.sh
解決: chomd +x ./build.sh

運(yùn)行test


屏幕快照 2021-03-18 下午10.16.19.png

成功被打印

dead_strip

通過如下命令我們查看一下 上面??我們編譯出來的 mach-O 看它的__Text section

objdump --macho -d test 
屏幕快照 2021-03-18 下午11.06.15.png
  • 可以看到包含靜態(tài)庫的符號 在連接的時(shí)候會(huì)把靜態(tài)庫的符號放在一起。保存在可執(zhí)行文件中构眯。

我們將main函數(shù)里使用到的方法去掉


屏幕快照 2021-03-18 下午11.09.36.png
  • 這里不妨停幾秒想一下 我們引入了頭文件 但是并沒有使用它里面的任何代碼愕难,那么生成的可執(zhí)行文件test有沒有包含 A_Manager.m中的代碼?

運(yùn)行我們的腳本 ./build.sh 再次查看 mach-O


屏幕快照 2021-03-18 下午11.12.00.png
  • 可以看到只有一個(gè)main 函數(shù) 這其實(shí)就是編譯器默認(rèn)的將沒有用到的符號給我們脫掉了惫霸。

這里我們想一個(gè)點(diǎn) 分類是在運(yùn)行時(shí)創(chuàng)建的還是 在編譯時(shí)創(chuàng)建的猫缭?肯定時(shí)運(yùn)行時(shí)了。
所以分類會(huì)出現(xiàn)問題壹店?

通過例子來展示

通過 workspace 來管理 兩個(gè) project 一個(gè)是主項(xiàng)目 一個(gè)是 我們的靜態(tài)庫Framework


屏幕快照 2021-03-19 上午12.06.57.png
  • 主工程調(diào)用了靜態(tài)庫A 的一個(gè) A_Test方法


    屏幕快照 2021-03-19 上午12.07.40.png
  • 靜態(tài)庫 A_Test方法調(diào)用了 分類 A+Test 的方法 testCategoryMethod方法


    屏幕快照 2021-03-19 上午12.08.10.png
  • A+Test 的方法打印

此時(shí)不妨想一想 會(huì)調(diào)用成功嗎饵骨?


屏幕快照 2021-03-19 上午12.13.36.png
  • 不成功又為啥?

這就是因?yàn)橛捎诜诸愂沁\(yùn)行時(shí)加載的茫打,所以 編譯器默認(rèn)將它符合進(jìn)行了死代碼剝離居触。

如何解決

-all_load : 全部加載不要給我脫
-ObjC : 只保留OC的其他的該脫脫
-force_load:指定 哪些靜態(tài)庫你需要脫

dead strip 兩種方案的區(qū)別

方案一

-noall_load /-all_load /-ObjC /-force_load<file> :在鏈接靜態(tài)庫的時(shí)候進(jìn)行死代碼刪除。

方案二

linking
dead Code Stripping : xxx 老赤,它是鏈接器給我們提供了一種優(yōu)化方式轮洋。

通過實(shí)操我們直觀的看一下他們的區(qū)別
沿用上面代碼

屏幕快照 2021-03-22 下午10.47.38.png
  • 寫一個(gè)全局符號 并在main函數(shù)中調(diào)用
  • 還寫了一個(gè)本地符號
  • 通過上篇文章我們寫的腳本編譯一下


    屏幕快照 2021-03-22 下午10.51.50.png
  • 此時(shí)我們想一下 我編譯出來的可執(zhí)行文件有沒有包含 libA_Manager.a這個(gè)靜態(tài)庫的代碼?
    沒有抬旺?為什么弊予?因?yàn)槲覀儧]有使用靜態(tài)庫的代碼所以它默認(rèn)是-noall_load
    我們來查看一下 我們編譯出來的 test mach-O
obdump --macho -d test 
屏幕快照 2021-03-22 下午10.59.37.png
  • 可以看到 并沒有 靜態(tài)庫的代碼

下面我們修改.sh 給連接器傳入 -all_load


屏幕快照 2021-03-22 下午11.03.20.png
  • 再次編譯并運(yùn)行

再次查看我們的 test mach-O


屏幕快照 2021-03-22 下午11.05.58.png
  • 此時(shí)發(fā)現(xiàn)我們沒有用到的靜態(tài)庫的函數(shù)也被存在了mach-o中,所以說方案一的參數(shù)設(shè)定對靜態(tài)庫來說是非常有用的开财。

下面我們看一下 ld的優(yōu)化方案 dead strip

屏幕快照 2021-03-22 下午11.14.29.png
  • 翻譯過來就是 移除代碼或方法汉柒,沒有被入口點(diǎn)或?qū)С龇栍玫降摹>蜁?huì)被刪除

我們再回過頭來看一下我們的test.m

屏幕快照 2021-03-22 下午11.17.38.png

我們在.sh 中拼接上 -dead_strip 再次編譯


屏幕快照 2021-03-22 下午11.19.50.png

在此查看一下符號表


屏幕快照 2021-03-22 下午11.26.30.png
  • 此時(shí)我們看到 明明 test.m我寫了一個(gè)全局符號责鳍,但是我并沒有用到碾褂,此時(shí)就會(huì)被干掉。

下面我們將其在main函數(shù)中使用历葛,再次編譯并查看符號表


屏幕快照 2021-03-22 下午11.29.15.png
  • 此時(shí)發(fā)現(xiàn) 現(xiàn)在它出現(xiàn)在了符號表中

從這里我們就可以分析出 dead_strip和我們的n-noall_load all_load 等 它并不是一個(gè)東西
它只是我們的鏈接器給我提供的一種優(yōu)化方式正塌,它是有一定規(guī)則的
1、沒有被我們?nèi)肟邳c(diǎn)使用就被干掉恤溶,
2乓诽、沒有被導(dǎo)出符號用到就會(huì)干掉

下面我在將 all_load 添加上


屏幕快照 2021-03-22 下午11.38.42.png

編譯并 再次查看符號表

屏幕快照 2021-03-22 下午11.39.44.png
  • 此時(shí)發(fā)現(xiàn) 除了OC的其他的全部被脫掉了 為啥?因?yàn)镺C是動(dòng)態(tài)語言現(xiàn)在給干掉它不敢啊咒程。

拓:還可以通過-Xlinker -why_live -Xlinker _xxxx 來查看這個(gè)符號為什么沒有被干掉


屏幕快照 2021-03-22 下午11.48.10.png

屏幕快照 2021-03-22 下午11.48.02.png

所以現(xiàn)在我們知道 dead strip 和 all_load /noall_load 是兩碼事鸠天。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者帐姻。
  • 序言:七十年代末稠集,一起剝皮案震驚了整個(gè)濱河市奶段,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌巍杈,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扛伍,死亡現(xiàn)場離奇詭異筷畦,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)刺洒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門鳖宾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人逆航,你說我怎么就攤上這事鼎文。” “怎么了因俐?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵拇惋,是天一觀的道長。 經(jīng)常有香客問我抹剩,道長撑帖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任澳眷,我火速辦了婚禮胡嘿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘钳踊。我一直安慰自己衷敌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布拓瞪。 她就那樣靜靜地躺著缴罗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祭埂。 梳的紋絲不亂的頭發(fā)上瞒爬,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機(jī)與錄音沟堡,去河邊找鬼侧但。 笑死,一個(gè)胖子當(dāng)著我的面吹牛航罗,可吹牛的內(nèi)容都是我干的禀横。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼粥血,長吁一口氣:“原來是場噩夢啊……” “哼柏锄!你這毒婦竟也來了酿箭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤趾娃,失蹤者是張志新(化名)和其女友劉穎缭嫡,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抬闷,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡妇蛀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了笤成。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片评架。...
    茶點(diǎn)故事閱讀 39,841評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖炕泳,靈堂內(nèi)的尸體忽然破棺而出纵诞,到底是詐尸還是另有隱情,我是刑警寧澤培遵,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布浙芙,位于F島的核電站,受9級特大地震影響籽腕,放射性物質(zhì)發(fā)生泄漏茁裙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一节仿、第九天 我趴在偏房一處隱蔽的房頂上張望晤锥。 院中可真熱鬧,春花似錦廊宪、人聲如沸矾瘾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽壕翩。三九已至,卻和暖如春傅寡,著一層夾襖步出監(jiān)牢的瞬間放妈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工荐操, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留芜抒,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓托启,卻偏偏與公主長得像宅倒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子屯耸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容