iOS Framework 瘦身總結(jié)

前言

隨著項目的進(jìn)行,iOS 端的 framework文件越來越大,已經(jīng)有些客戶開始抱怨了,iOS 端的 framework瘦身也就相應(yīng)的提上了日程,這里對我們 Framework 瘦身進(jìn)行了一個小結(jié)。

1. 精簡代碼

這一步效果不是很大,主要對頭文件的引用、重復(fù)代碼、無用代碼等進(jìn)行了梳理。

2. 編譯優(yōu)化

2.1 優(yōu)化ROI(Optimization Level)

XCode編譯優(yōu)化選項中,Optimization Level效果最明顯,建議所有模塊構(gòu)建都開啟Oz選項。如果APP有動態(tài)庫,并且依賴了openssl等基礎(chǔ)靜態(tài)庫,建議和APP工程共享,并通過EXPORTED_SYMBOLS_FILE的選型,確保動態(tài)庫中需要用到的符號都在編譯過程保留。

項目中 Release 模式配置成 [-OZ],其他模式配置成Fastest,Smallest[-OS]

2.2 LTO 配置

Link-Time OptimizationLLVM 編譯器的一個特性,用于在 link中間代碼時,對全局代碼進(jìn)行優(yōu)化。這個優(yōu)化是自動完成的,因此不需要修改現(xiàn)有的代碼;這個優(yōu)化也是高效的,因為可以在全局視角下優(yōu)化代碼。

它的優(yōu)化主要體現(xiàn)在如下幾個方面:

1.多余代碼去除(Dead code elimination):如果一段代碼分布在多個文件中,但是從來沒有被使用,普通的 -O3 優(yōu)化方法不能發(fā)現(xiàn)跨中間代碼文件的多余代碼,因此是一個“局部優(yōu)化”。但是 Link-Time Optimization 技術(shù)可以在 link 時發(fā)現(xiàn)跨中間代碼文件的多余代碼;

  1. 跨過程優(yōu)化(Interprocedural analysis and optimization):這是一個相對廣泛的概念。舉個例子來說,如果一個 if 方法的某個分支永不可能執(zhí)行,那么在最后生成的二進(jìn)制文件中就不應(yīng)該有這個分支的代碼;

3.內(nèi)聯(lián)優(yōu)化(Inlining optimization):內(nèi)聯(lián)優(yōu)化形象來說,就是在匯編中不使用 “call func_name ” 語句,直接將外部方法內(nèi)的語句“復(fù)制”到調(diào)用者的代碼段內(nèi)。這樣做的好處是不用進(jìn)行調(diào)用函數(shù)前的壓棧、調(diào)用函數(shù)后的出棧操作,提高運(yùn)行效率與??臻g利用率。

同時也有以下幾個缺點(diǎn):

1.降低編譯鏈接速度,只建議在打正式包時開啟

2.降低 link map 可讀性(出現(xiàn)XX-lto.thin的類)

Link-Time Optimization 選項在 Release模式下配置成 Incremental,其他模式配置成 No

2.3 Strip Linked Product

如果為 YES,則進(jìn)行裁剪(在編譯最后對 framework 進(jìn)行 strip));如果為NO,則不進(jìn)行裁剪;至于裁剪什么級別的符號由 Strip Style 配置決定;如果Deployment Postprocessing為NO,Strip Linked Product設(shè)置無效;

Strip Linked Product 選項在 Release模式下配置成 YES,其他模式配置成 No

2.4 Deployment Postprocessing

如果為 YES,在編譯生成目標(biāo)文件之后要進(jìn)行后續(xù)處理;如果為 NO,則不會有后續(xù)處理;使用 Xcode Archive 進(jìn)行編譯,Deloyment Postprocessing 的值恒為YES;

Deployment Postprocessing 選項在 Release模式下配置成 YES,其他模式配置成 No

2.5 Strip Style

  • Debugging Symbols :會將調(diào)試符號從二進(jìn)制中刪除掉,即去除 DWARF 信息;
  • Non-Global Symbols :會將局部符號和調(diào)試符號從二進(jìn)制中刪除掉,即去除 DWARF 信息以及部分 Symbol Table 中的信息;
  • All Symbols :去除全部符號,即去除 DWARF 中的調(diào)試信息以及Symbol Table 中目標(biāo)模塊定義的全局、局部符號信息。

Strip Style 選項在 Release模式下配置成 Non-Global Symbol,其他模式配置成 Debugging Symbols

2.6 Symbols Hidden by Default

這是全局的開關(guān),用來設(shè)置符號的默認(rèn)可見性,設(shè)置為YES,會把所有符號都定義成”private extern”;

也可以可以使用編譯器屬性attribute((visibility("default")))和attribute((visibility("hidden")))來控制符號的可見性;

__attribute__((visibility("default"))) void MyFunction1() {} //可見
__attribute__((visibility("hidden"))) void MyFunction2() {}  //不可見

Symbols Hidden by Default 選項在 Release模式下配置成 YES,其他模式配置成 NO

設(shè)置 Symbols Hidden by Default為 YES 后會默認(rèn) OC 的類是 hidden的,因此需要將對外暴露的類用__attribute__((visibility("default"))) 修飾

2.7 Dead Code Stripping

Dead Code Stripping開啟后會在鏈接時移除未使用的代碼,它對靜態(tài)語言C/C++/Swift有效,對動態(tài)語言O(shè)C無效。
Dead Code Stripping 選項在 Release模式下配置成 YES,其他模式配置成 NO

2.8 Generate Debug Symbols

是否生成符號文件,設(shè)置為NO;這樣才能支持?jǐn)帱c(diǎn)調(diào)試;注意Debug模式下,Deployment Postprocessing 一定要NO,否則Generate Debug Symbols的設(shè)置了YES,也不支持?jǐn)帱c(diǎn)調(diào)試;

Generate Debug Symbols 選項在 Release模式下配置成 YES,其他模式配置成 NO

2.8 C++去掉RTTI支持

Eable C++ Runtime Types 選項在 Release模式下配置成 NO,其他模式配置成 YES
同時還需要在 OTHER_CFLAGS里面添加-fno-rtti

2.9 C++只導(dǎo)出必要符號:Symbol Visibility

OTHER_CFLAGS中添加-fvisibility=hidden

需要導(dǎo)出的符號 設(shè)置需要導(dǎo)出的符號

__attribute__((visibility("default"))) void MyFunction1() {} 
__attribute__((visibility("default"))) void MyFunction2() {} 

2.10 Strip Debug Symbols During Copy

Strip Debug Symbols During Copy 選項在 Release模式下配置成 YES,其他模式配置成 NO

2.11 Enable BitCode

Enable BitCode 關(guān)掉后編譯出來的 framework 會更小,目前考慮大多數(shù)項目都是打開的,配置打開狀態(tài)

2.12 Mach-O Type

Mach-O Type 設(shè)置成 Dynamic Library , 動態(tài)的framework是允許的上線的不會拒絕, 設(shè)置成Dynamic Library后能解決掉大多數(shù)由于依賴相同第三方庫而引起的符號沖突問題。包也會比靜態(tài) framework 小很多

2.13 Exported Symbols File

EXPORTED_SYMBOLS_FILE 可以傳入一個符號表白名單列表,在這個名單里面的符號符號會暴露給外部,不在該名單的的符號會隱藏。

  • 如何看 iOS 動態(tài)/靜態(tài)庫的符號表,可以去了解下nm命令

寫在最后

通過上面步驟對我們的 SDK 項目進(jìn)行瘦身,將arm64和 armv7兩個架構(gòu)包的總大小降低30%和同行 SDK 包大小基本一致。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 安裝包組成: 談到 App 瘦身,最直接的想法莫過于分析一個安裝包內(nèi)部結(jié)構(gòu),了解其每一部分的來源。解壓一個 ipa...
    孔雨露閱讀 3,527評論 1 7
  • iOS 安裝包瘦身 一. 安裝包組成 談到 App 瘦身,最直接的想法莫過于分析一個安裝包內(nèi)部結(jié)構(gòu),了解其每一部分...
    iYeso閱讀 1,485評論 5 9
  • 記錄一次安裝包大小優(yōu)化的實踐。維持安裝包體積是一個持續(xù)的過程,建立預(yù)警機(jī)制,監(jiān)控每個版本的體積大小。 資源文件優(yōu)化...
    bluedaquiri閱讀 2,420評論 0 4
  • 背景 包大小優(yōu)化是項目開發(fā)中不可避免會遇到的,網(wǎng)上關(guān)于包大小優(yōu)化的文章很多,每篇文章說的都不盡相同,筆者曾經(jīng)根據(jù)網(wǎng)...
    大菠蘿_DABLO閱讀 5,471評論 0 12
  • 背景 移動開發(fā)中,對于包大小優(yōu)化是項目開發(fā)中需要考慮的,尤其對于航母級App,比如QQ、手淘等。網(wǎng)上關(guān)于包大小優(yōu)化...
    virusbo閱讀 4,878評論 1 18

友情鏈接更多精彩內(nèi)容