1. 程式人生 > >怎樣減小iOS APP 或者 靜態庫的體積

怎樣減小iOS APP 或者 靜態庫的體積

編譯選項

1.編譯器優化級別

Build Settings->Optimization Level有幾個編譯優化選項,release版應該選擇Fastest, Smalllest,這個選項會開啟那些不增加程式碼大小的全部優化,並讓可執行檔案儘可能小。

2.去除符號資訊

Strip Linked Product / Deployment Postprocessing / Symbols Hidden by Default 在release版本應該設為yes,可以去除不必要的除錯符號。Symbols Hidden by Default會把所有符號都定義成”private extern”,詳細資訊見

官方文件

這些選專案前都是XCode裡release的預設選項,但舊版XCode生成的專案可能不是,可以檢查一下。其他優化還可以參考官方文件—CodeFootprint.pdf

第三方庫統計

專案裡會引入很多第三方靜態庫,如果能知道這些第三方庫在可執行檔案裡佔用的大小,就可以評估是否值得去找替代方案去掉這個第三方庫。我們可以從linkmap中統計出這個資訊,對此寫了個node.js指令碼,可以通過linkmap統計每個.o目標檔案佔用的體積和每個.a靜態庫佔用的體積,詳見這裡(需翻牆)。

ARC->MRC

有人提出用ARC寫的程式碼編譯出來的可執行檔案是會比用MRC大的,原因大致是ARC程式碼會在某些情況多出一些retain和release的指令,例如呼叫一個方法,它返回的物件會被retain,退出作用域後會被release,MRC就不需要,彙編指令變多,機器碼變多,可執行檔案就變大了。還有其他細節實現的區別,先不糾結了。

那用ARC究竟會增大多少體積?我覺得從彙編指令的增多減少去算是很難算準確的,這東西涉及細節太多,還是得從統計的角度計算。做了幾個對比試驗,統計了幾個同時支援ARC/MRC的開源專案在開啟/關閉ARC的情況下__TEXT程式碼段的大小對比。只對比__TEXT程式碼段是因為:

  1. ARC對可執行檔案大小的影響幾乎都是在程式碼段
  2. 可執行檔案會進行某種對齊,例如有些段在不足32K的時候填充0直到對齊32K,若用可執行檔案大小對比結果可能是對齊後的,不準確。

實驗資料:

MBProgressHUD

SDWebImage

FMDB

開啟ARC

19532

24424

29056

關閉ARC

17648

22575

25848

對比

↓9.6%

↓7.5%

↓11%

結果是ARC大概會使程式碼段增加10%的size,考慮程式碼段佔可執行檔案大約有80%,估計對整個可執行檔案的影響會是8%。

可以評估一下8%的體積下降是不是值得把專案裡某些模組改成MRC,這樣程式的維護成本上升了,一般不到特殊情況不建議這麼做。

無用程式碼

在專案裡新建一個類,給它新增幾個方法,但不要在任何地方import它,build完專案後觀察linkmap,你會發現這個類還是被編譯進可執行檔案了。

按C++的經驗,沒有被使用到的類和方法編譯器都會優化掉,不會編進最終的可執行檔案,但object-c不一樣,因為object-c的動態特性,它可以通過類和方法名反射獲得這個類和方法進行呼叫,所以就算在程式碼裡某個類沒被使用到,編譯器也沒法保證這個類不會在執行時通過反射去呼叫,所以只要是在專案裡的檔案,無論是否又被使用到都會被編譯進可執行檔案。

對此我們可以通過指令碼,遍歷整個專案的檔案,找出所有沒有被引用的類檔案和沒有被呼叫的方法,在保證沒有其他地方動態呼叫的情況下把它們去掉。如果整個專案歷時很長,歷時程式碼遺留較多,這個清理對可執行檔案省出的空間還是挺可觀的。

類/方法名長度

觀察linkmap可以發現每個類和方法名都在__cstring段裡都存了相應的字串值,所以類和方法名的長短也是對可執行檔案大小是有影響的,原因還是object-c的動態特性,因為需要通過類/方法名反射找到這個類/方法進行呼叫,object-c物件模型會把類/方法名字串都儲存下來。

對此我們可以考慮在編譯前把所有類和方法名進行混淆,跟壓縮js一樣,把長名字替換成短名字,這樣做的好處除了縮小體積外,還對安全性有很大提升,別人拿到可執行檔案對它class-dump出來的結果都是混淆後的類和方法名,就無法從類和方法名中猜出某個方法是做什麼的,就難以掛鉤子進行hack。不過這樣做有個缺點,就是crash堆疊反解出來的堆疊方法名會是混淆後的,需要再加一層混淆->原名的轉換,實現和使用成本有點高。

實際上這部分佔用的長度比較小,中型專案也就幾百K,對安全性要求高的情況可以試試。

冗餘字串

程式碼上定義的所有靜態字串都會記錄在在可執行檔案的__cstring段,如果專案裡Log非常多,這個空間佔用也是可觀的,也有幾百K的大小,可以考慮清理所有冗餘的字串。另外如果有特別長的字串,建議抽離儲存成靜態檔案,因為AppStore對可執行檔案加密導致壓縮率低,特別長的字串抽離成靜態資原始檔後壓縮率會比在可執行檔案裡高很多。

CheckList

最後把縮減iOS安裝包大小的各種方法列出來做了張CheckList圖:

安裝包大小優化

參考文獻:http://blog.cnbang.net/tech/2296/


相關推薦

怎樣減小iOS APP 或者 靜態體積

編譯選項 1.編譯器優化級別 Build Settings->Optimization Level有幾個編譯優化選項,release版應該選擇Fastest, Smalllest,這個選項會開啟那些不增加程式碼大小的全部優化,並讓可執行檔案儘可能小。 2.去除符號資訊 Strip Linke

iOS編譯OpenSSL靜態(使用指令碼自動編譯)

使用指令碼編譯:https://github.com/gitusrs/openssl-ios-build-shell-script 1、該指令碼只是一個OpenSSL編譯指令碼,使用時需要自己下載OpenSSL原始碼(openssl-*.tar.gz) 2、將 openssl-

ios開發之靜態(.a)的生成及使用

一、靜態庫定義:         在應用中,有些公共的程式碼需要反覆使用 的程式碼,希望隱藏程式碼的具體實現,可以把這部分程式碼做出靜態庫(.a檔案);如果提供庫的原始碼稱為開源庫(能看見.h也能看見.m檔案),不提供原始碼的庫稱為閉源庫(靜態庫,動態庫) 二、靜態庫的特

iOS svn提交靜態.a檔案

使用命令列新增檔案 1.開啟終端,輸入cd,空格,然後將需要上傳的.a檔案所在的資料夾(不是.a檔案)拖拽到終端(此辦法無需輸入繁瑣的路徑,快捷方便) ,回車; 2.之後再輸入如下命令:svn add libOCMock.a,回車; 3.之後會出現:A  (bin)  

iOS打包.a靜態步驟

打包靜態庫流程 1.建立靜態庫 2.實現類 3.公開.h檔案 4.打包模擬器靜態庫 5.打包真機靜態庫 6.合併模擬器 和 真機 靜態庫 7.測試靜態庫 一、前期工作 1、新建.a靜態

iOS開發之靜態(三)—— 圖片、介面xib等資原始檔封裝到.a靜態

轉自:https://blog.csdn.net/mylizh/article/details/38707175編譯環境:Macbook Air + OS X 10.9.2 + XCode5.1 + iPhone5s(iOS7.0.3)一、首先將資原始檔打包成bundle新建

iOS中 Framework靜態的建立和使用遇到的那些坑 韓俊強的部落格

前言網上關於Framework製作的教程數不勝數,然而都過於陳舊,最新的也是使用Xcode7的教程,而且有些設定也只給出步驟,並沒有給出原因,而且按照有些教程製作出的framework還有些問題,所以我

iOS 引用外部靜態(.a檔案)時,Category方法無法載入問題

問題: +[UIImage imageNamedFromBundleWithPNG:]: unrecognized selector sent to class 0x199812698 解決方法為:找到 target 的圖示,更改其 Other Linker Flags

iOS APP優化之--IPA體積優化

專案中在對IPA體積的優化 首先需要了解下ipa包的組成: ipa是一個壓縮包, 安裝包裡的主要構成是(圖片+文件+二進位制檔案) 接下來會對各個部分分別嘗試優化處理已減小安裝包體積: 1.圖片: 使用這個指令碼工具可以大範圍檢測程式中沒有用到的圖片

Android-CMakeLists.txt 連結第三方(動態或者靜態)到自己的生成

最近在做關於NDK開發的專案,編譯方式通過cmake。其中一個就是要將第三方動態庫連結到自己的動態庫最終生成一個動態庫供他人呼叫,這個折騰了好久,終於搞好記錄下筆記,免得以後再踩坑,有同樣需求的童鞋可以參考,有錯誤請指出。多的不說,上程式碼.1.首先看目錄結構:第三方庫放在j

iOS 學習日誌 : 靜態的生成

有的時候會需要做靜態庫的需求,於是試著做了一下 (Xcode 7.2) 1.首先選擇建立靜態庫 2.寫兩個簡單的例項方法和類方法,實現裡只做簡單的輸出 3.在Xcode -> Product ->Scheme ->Edit Sch

iOS Xcode打包靜態framework

iOS中.a與.framework庫的區別 從上面我們可以看出.a 和.framework的區別就是.a+.h+soureFile=.framework,這樣的話,我們還是直接封裝個.framework比較好。 封裝framework步驟 1、開啟xcode,新建工

iOS開發之-靜態

【靜態庫是什麼】 簡單來說。。。一個靜態庫是若干個類,函式,定義和資源的包裝,你可以將其打包並很容易的在專案之間共享。。。大家平時開發中看到的.a檔案。。。其實也就是一個靜態庫檔案。。。 在開發的過程中我們會發現。。。有時候你匯入了一些第三方框架。。。只看到.h檔案。。。卻

IOS 靜態的和.framework制作

https works select 其它 開源庫 sta cat neo working 什麽是庫? 庫是程序代碼的集合,是共享程序代碼的一種方式 根據源代碼的公開情況,庫可以分為2種類型 開源庫 公開源代碼,能看到具體實現 比如SDWebImage、AFNetwor

CoreData(數據升級 )版本遷移-iOS App升級安裝

版權 取數據 多版本 系統默認 新建 庫存 object edit 沒有 版權聲明:本文為博主原創文章,未經博主允許不得轉載。 如果IOS App 使用到CoreData,並且在上一個版本上有數據庫更新(新增表、字段等操作),那在覆蓋安裝程序時就要進行CoreData數

iOS 使用 Xcode8 制作動態靜態

三方 不想 -1 有關 module user pub nes 也有   在使用第三方 SDK 時,經常遇到他們提供的僅僅只有一個動態或靜態庫,並不能獲取源碼。使用動態庫 FrameWork 或 靜態庫 Lib,可以滿足不想把核心代碼的具體實現向使用者展示,又能避免其他人錯

如何打包靜態.a文件 iOS

gson 打包成 round -1 creat public ima create 別人 代碼調試好了開始打包成sdk,下面是將要打包的FRSDK代碼(FRSDK.h暴露在外面有別人調用) 1.創建新工程(Xcode File-New-Project) 2.把下面的紅

iOS封裝功能生成靜態.Framework

pos scree 靜態 模擬器 master screens 實現 gpo tin 在實現iOS模塊化開發的過程中,可以把固定的業務模塊生靜態庫. 本文將基於Xcode9.2創建一個簡單的工程,教大家如何制作一個自己的framework,目的就是簡單易學的制作framew

iOS裡的動態靜態

介紹 動態庫形式:.dylib和.framework 靜態庫形式:.a和.framework 動態庫和靜態庫的區別 靜態庫:連結時,靜態庫會被完整地複製到可執行檔案中,被多次使用就有多份冗餘拷貝(圖1所示) 系統動態庫:連結時不復制,程式執行時由系統動態

iOS拆分,合併靜態以壓縮打包空間

需求:拆分iOS中體積較大的第三方靜態庫以實現軟體瘦身. 閱讀前提: 瞭解各種架構的靜態庫含義 瞭解如何使用Terminal 簡書地址 : 拆分iOS靜態庫 部落格地址 : 拆分iOS靜態庫 掘金地址 : 拆分iOS靜態庫 基本介紹 一般靜態庫中支援真機和模擬器多種CP