iOS可执行文件瘦身方法
缩减iOS安装包大小是很多中大型APP都要做的事,一般首先会对资源文件下手,压缩图片/音频,去除不必要的资源。这些资源优化做完后,我们还可以尝试对可执行文件进行瘦身,项目越大,可执行文件占用的体积越大,又因为AppStore会对可执行文件加密,导致可执行文件的压缩率低,压缩后可执行文件占整个APP安装包的体积比例大约有80%~90%,还是挺值得优化的。下面介绍一下在研究可执行文件过程中发现的可以优化的点。研究的过程使用了linkmap,linkmap的介绍跟生成可以参考另一篇文章—iOS可执行文件的组成。
编译选项
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静态库占用的体积,详见这里(需FQ)。
ARC->MRC
有人提出用ARC写的代码编译出来的可执行文件是会比用MRC大的,原因大致是ARC代码会在某些情况多出一些retain和release的指令,例如调用一个方法,它返回的对象会被retain,退出作用域后会被release,MRC就不需要,汇编指令变多,机器码变多,可执行文件就变大了。还有其他细节实现的区别,先不纠结了。
那用ARC究竟会增大多少体积?我觉得从汇编指令的增多减少去算是很难算准确的,这东西涉及细节太多,还是得从统计的角度计算。做了几个对比试验,统计了几个同时支持ARC/MRC的开源项目在开启/关闭ARC的情况下__TEXT代码段的大小对比。只对比__TEXT代码段是因为:
- ARC对可执行文件大小的影响几乎都是在代码段
- 可执行文件会进行某种对齐,例如有些段在不足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图:

iOS可执行文件瘦身方法的更多相关文章
- 【转】iOS可执行文件瘦身方法
http://blog.cnbang.net/tech/2544/ 缩减iOS安装包大小是很多中大型APP都要做的事,一般首先会对资源文件下手,压缩图片/音频,去除不必要的资源.这些资源优化做完后,我 ...
- iOS 可执行文件瘦身方法
编译选项 1.编译器优化级别 Build Settings->Optimization Level有几个编译优化选项,release版应该选择Fastest, Smalllest,这个选项会开启 ...
- iOS代码瘦身实践
1 分析当前ipa的组成 一般一个ipa会包含: 1) 资源文件 本地文件:数据.配置.数据库等等 字体文件 图片资源 2) 源代码 通过生成linkmap文件,分析源代码生成的编译文件的大小.在B ...
- iOS App 瘦身方案
缩减iOS安装包大小是很多中大型APP都要做的事,一般首先会对资源文件下手,压缩图片/音频,去除不必要的资源.这些资源优化做完后,我们还可以尝试对可执行文件进行瘦身,项目越大,可执行文件占用的体积越大 ...
- iOS图片瘦身总结
前言 最近在公司写了个小程序来为iOS应用中的图片瘦身,进而减小APP大小,减少用户下载时的流量. 瘦身是在一个专门为图片瘦身的网站进行的. 地址:https://tinypng.com 这个网站提供 ...
- iOS控制器瘦身-面向超类编程
今天写这篇文章的目的,是提供一种思路,来帮助大家解决控制器非常臃肿的问题,对控制器瘦身. 滴滴 老司机要开车了 如果手边有项目,不妨打开工程看一下你的控制器代码有多少行,是不是非常多?再看一下tabl ...
- golang可执行文件瘦身(缩小文件大小)
起因 golang部署起来极其遍历,但有时候希望对可执行文件进行瘦身(缩小文件大小) 尝试 情况允许情况下,交叉编译为32位 删除不必要的符号表.调试信息 尝试用对应平台的upx打压缩壳 解决 经过多 ...
- iOS ViewControllers 瘦身
https://objccn.io/issue-1-1/ https://juejin.im/user/57ddfba4128fe10064cbb93a 把 Data Source 和其他 Proto ...
- Android APK瘦身方法小结
众所周知,APP包体的大小,会影响推广的难度,用户不太喜欢下载太大的APP,同类型同等功能的APP中往往是包体小的更受用户的青睐,所以降低包体是一项非常必要的事情,也是最近公司的APP需要降低包体,所 ...
随机推荐
- EntityFramework之一对一关系(二)
前言 关于表关系园中文章也是数不胜收,但是个人觉得最难攻克的是一对一,对其配置并非无道理可循,只要掌握了原理方可,且听我娓娓道来! 共享主键关系 概念:就是两个表共享相同的主键值,也就是说一表的主键值 ...
- sublime3破解版sublime3注册码
Sublime Text 3 官方网址:http://www.sublimetext.com/ Mac下载地址: http://c758482.r82.cf2.rackcdn.com/Sublime% ...
- 为SharePoint 站点添加通知
作为思想.内容的共享型产品,SharePoint 不出意外的成为其中最好用的产品之一,想想平时在公司中接到通知并了解通知内容是件很平常的事情,那让这种平常的事情进入到SharePoint中可以通过如下 ...
- ZOJ Problem Set - 1216 Deck
#include <stdio.h> int main() { ]; double t=2.0; table[]=0.5; ;i<;i++) { t+=; table[i]=tabl ...
- Oracle Database Server 'TNS Listener'远程数据投毒漏洞(CVE-2012-1675)解决
环境:Windows 2008 R2 + Oracle 10.2.0.3 应用最新bundle patch后,扫描依然报出漏洞 Oracle Database Server 'TNS Listener ...
- CloudNotes:一个云端个人笔记系统
很长时间没有更新博客了,一直在忙着工作和生活琐事,虽然偶尔也有闲暇之时,但短短的几个小时空闲又未必能够静下心来.最近一个多月突发奇想,将自己在近一年前做的一个自己用的云端个人笔记系统重构美化了一下,增 ...
- WPF语音播放MediaPlayer
private MediaPlayer player; public MainWindow() { InitializeComponent(); player = new MediaPlayer(); ...
- html5数字和颜色输入框
html5功能强大,数字和颜色输入框例子 效果:http://hovertree.com/code/html5/rxujb6g8.htm <!DOCTYPE html> <html& ...
- ios 学习笔记之控件属性
1.文本框 设置密码属性:Secure Text Entry 勾选; 设置文本框带清除属性: Clear Button =Is always visible; 默认是不带清除属性:Never app ...
- C程序范例(2)——学生管理系统”链表“实现
1.对于学生管理系统,能够实现的方法有许多,但是今天我们用链表的方法来实现.虽然初学者很可能看不懂,但是不要紧,这是要在整体的系统的学习完C语言之后,我才编写出的程序.所以大家不必要担心.在这里与大家 ...