面对如今不断迭代的iOS APP,在产品需求以及功能模块的持续扩大下,应用包大小也会随之变得越来越大,当代码量达到一定程度后,对于一个持续性的大型项目来说应用包瘦身是一个迫在眉睫的问题。
当我们谈及应用包瘦身,无非就是从两个层面应对,一个是资源级别的优化,一个就是代码级别的优化,接下来我们就从这两个方面下手:
一.资源级别
1. 剔除被工程引用但没有实际使用的资源文件
应用包中的资源文件包括图片资源、音频资源、视频资源以及其他配置文件,这些往往占据了应用包中的很大一部分空间,在持续性开发过程中会不断添加新的功能模块,同时也会移除一些不再使用的模块,有时候我们不一定会完全移除我们不再使用模块的资源,使得这些废弃的资源还会在工程中引用并一起会被打入到包中,这时候我们会用到一个检查工程项目中无用图片资源的工具LSUnusedResources,搜索结果中的资源文件都为被引用但没有实际使用(为确保安全无误,删除前还需要确保工程中没有使用)。
2.选择合适的资源导入方案
资源文件有很多种方案加入到工程项目中:
- Assets.xcassets :只支持PNG格式,通过[UIImage imageNamed:]加载,无法通过Bundle加载
- CreateGroup:可通过[UIImage imageNamed:]加载,通过Bundle加载效率高
- CreateFolderRefences:无法通过[UIImage imageNamed:]加载,通过Bundle加载效率差
这几种导入方案会对打出的包大小有些影响,通过CreateGroup、CreateFolderRefences两种方式打出来的包,图片资源不会做改动,直接放在.app包文件中,打包的前后图片资源大小不会改变,而加入到Assets.xcassets中的方式是在。app中生成Asset.car文件来存储放入的图片资源,是对图片资源进行了一次压缩,因此文件大小会降低,综上所述,尽量使用Asset.xcassets的方式来导入资源文件能有效的控制APP包的大小。
二.代码级别
首先呢,我们需要知道应用包中各个类以及第三方库占用的空间比例,从而能有针对性的对不同模块进行分析,这时候可以通过LinkMap来分析我们的工程项目中各个类或者库所占用的空间大小,分析结束后就可以快速定位到需要进行优化的类或者静态库。当我们知道工程项目中的第三方库在可执行文件里占用空间大小时,就可以具体分析权衡是否有其他方案替代这些第三方库。
由于OC的动态性,它可以通过类和方法名反射获得这个类和方法进行调用,所以就算在代码里某个类没有被使用到,编译器也无法保证这个类不会再运行时通过反射去调用,因此只要是在项目中引用的文件,无论是否被使用到都会被编译进可执行文件中。这种情况下我们就需要找到工程项目中没有被最终调用的方法以及没有用过的类,这些得以剔除也会使包大小变下很多,知道这些就可以从代码中如何找到未被最终调用的方法以及无用的类入手。
下面就介绍几个对于代码瘦身方面有用的工具:
1. fui命令行工具
这个工具是用来找出OC项目中未用到OC的头文件引用
安装:
gem install fui
帮助:
fui help
在当前目录下检索未使用类:
fui find
在目标路径下检索未使用类:
fui --path=~/source/project/Name find
删除所有未引用类文件
fui --path=~/source/project/Name delete --preform --prompt
2.Clang插件XcodeZombieCode
第二个就是来自滴滴的王康基于clang插件这样一个源码级别的分析工具来分析代码间的调用关系达到分析出无用代码的目的, CLANG技术分享系列四:IOS APP无用代码/重复代码分析
要使用clang插件,具体步骤如下:
1.clang环境搭建,找到xcode对应的clang版本 并且官网查询对应发布版本下载并编译
2.编译XcdoeZombieCode 插件代码生成插件(dylib)。
3.要在Xcode中使用Clang插件,需要XcodeHacking.zip
执行以下两个命令:
sudo mv HackedClang.xcplugin `xcode-select -print-path`/../PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins
sudo mv HackedBuildSystem.xcspec `xcode-select -print-path`/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Specifications
4.配置调用插件的Xcode项目
a.Xcode配置
b.添加other_flags
-Xclang -load -Xclang pluginPath/XcodeZombieCode.dylib -Xclang -add-plugin -Xclang XcodeZombieCode
注:pluginPath/XcodeZombieCode.dylib为生成插件dylib的地址
5.使用clang编译Xcode
3. SMCheckProject
由于clang插件检索出的无用方法没法确定能够直接删除,还需要挨个检索人工判断是否可以删除,这样每次要清理是需要人工排查一遍是非常耗时耗力的。这里推荐一个使用Swift3写的MacOS程序,这个工具可以很方便快捷的找出工程项目下未被调用的方法可以检测出objc项目中无用的方法,支持一键清理。
最后说两句
我觉得在平时的开发过程中,尽量保证同样的功能或者组件模块能够尽量在不影响代码可读性的同时抽取出来使代码达到一个精简的程度,还有就是资源文件不要自己在工程项目中新建目录了,最好都放在苹果官方给的Assets里面。