Unity引擎IOS执行档大小优化

简介

苹果对于IOS执行档的大小是有明确的限制的,其中TEXT段的大小不能超过80M,否则提审将会被苹果拒绝,同时,如果TEXT段过于太大,那么在苹果进行加密之后,很容易出现解压失败等各种异常,最终导致游戏无法正常运行。因此,理论上我们应该尽可能保持我们的执行档TEXT段大小小于80M,根据经验,始终保持在60-70M以下是相对比较保险的。请注意,这里说的80M是包含armv7和arm64两种架构的执行档的TEXT段之和而并非单个架构,即单个架构的TEXT段大小不能超过40M。

IOS的执行档格式为mach-o格式,关于这种个是可以看苹果的文档或者维基百科。另外有工具Mach-o Viewer可以帮助你检阅这些信息。

查看TEXT段大小的方法

首先简单介绍查看执行档TEXT段大小的方法。在Mac系统下,使用XCode生成项目之后,生成的执行档都在DerivedData目录下,这个目录可以使用Command + Shift + G跳转过去,目标地址:

~/资源库/Developer/Xcode/DerivedData/

可以简单通过子目录的时间戳分析出最近的生成位于哪个目录下,依次向前即可找到生成的执行档,这是一个包。查看包内容,里面会有一个同名的可执行文件,此文件可以等效于Windows下面的exe文件。可以将其复制到桌面或者其它地方,也可以不复制。打开终端,进入对应目录。使用命令size即可显示执行档的各段的大小数据,如:

Bodong-iMac:Documents bodong$ size ./xxgame

__TEXT        __DATA __OBJC others dec hex

34373632 10518528 0 2179072 47071232 2ce4000 ./xxgame (for architecture armv7)

39534592 17203200 0 4296835072 4353572864 1037e4000 ./xxgame (for architecture arm64)

上面加粗的数据即是TEXT段的大小,最终的TEXT段的大小为两种架构大小之和。倘若它们之和大于80M,你的执行档可能会被苹果拒绝。

为什么要强调Unity

如果我们直接使用C++开发,一般来说并不会有关于TEXT段太大的问题,然而Unity不一样,Unity使用的mono C#开发,在build时通过il2cpp将C#代码编译结果翻译成C++代码,由于il2cpp翻译的C++代码需要模拟很多C#的行为,因此它本身生成的代码量会远远高于实现这些功能所需要的C++代码数量。代码体积巨大的结果就是TEXT段大小会超标,这样会对游戏发布产生巨大的影响。

这里我选择了我自己的一个非常简单的项目来做实例进行展示,代码很少,因此并不会造成TEXT段过大的问题,但是当你的项目足够大时,就会有问题了。这里用于展示,原理是一样的。

Unity对IOS生成的结果是一个Xcode项目。其中在Classes/Native下面,就是我们生成的代码,如果这个文件夹的总大小超过了300M,那请注意,你的执行档TEXT段可能就要超标了。因此大多数的优化目的都是为了减小这个Native文件夹的总大小,根据经验,这里减少5m左右,执行档TEXT段就可以减少1m。

具体技术细节

有很多方法可以减少Native文件夹的大小,这里依依列出。另外部分优化的具体数据由于时间问题已经记不清了,只能记得大概的数据。

1.一定使用Release编译,一定使用非Development Build。

2.项目Build Player Setting中,Api Compatibility Level一定要采用.net 2.0 subset。可减少数M。

3.strip一定要开,unity4里面选择strip level选择strip by byte code,选择micro mscorlib可能会导致crash,可以先不考虑;unity5中勾上strip Engine Code。可减少数M。

4.移除非必须使用的.net基础库,比如System.xml,可以使用其它更精简的库代替。比如System.xml的替代者SecurityParser。移除这个大模块后,可减少TEXT段3-5M。同理,System.Linq也应该尽量不用,其一是容量问题,其二是效率问题,其三是在iphone4s下面可能导致crash的问题。

5.少用或不用模板。在早期的unity版本(4.6.6之前),尤为甚之。模板会导致代码量剧烈膨胀,要查看自己的模板代码总共贡献了多少C++代码,可以在native文件夹中搜搜Generic,其中有大部分C++代码就是模板的贡献。

倘若你的模板生成的C++代码总数量大于了40m,那你应该提高警惕。造成这些暴涨的主要元凶就是System.Collection.Generic下面的各种容器,比如List,Dictionary,其解决方案就是针对class类型的类型衰减。我已经提供了新的ListView和DictionaryView,DictionaryObjectView容器,它们不会导致模板生成代码暴涨。相关代码可以在我的一个开源项目CheatConsole中找到,地址:https://github.com/sczybt/CheatConsole

6.统一使用C#,不要使用javascript或者boo,哪怕只有一个javascript或者boo代码文件,都会导致Unity引用两个你根本不需要的库Unity.Lang和Boo.Lang。这个可以通过在Native文件夹下面搜索名字包含Lang的C++文件来验证。这个要求也包括第三方库,如果第三库中有这些代码,也会产生问题。

7.移除不再使用的代码。比如一些三方库的Example代码,永远用不到的组件等等。

8.尽量升级到新版本的Unity,一般来说新版本较旧版本都会在这方面做一些优化。比如4.6.6相比4.6.5就优化了大约30%以上的生成代码容量。

总结

使用了如上策略之后,我们项目的执行档大小从最初的300m减小到90m,TEXT段大小从190M减小到70M。大家可以对这些方法进行验证,并提前做好预防工作。

时间: 2024-12-28 12:05:15

Unity引擎IOS执行档大小优化的相关文章

unity profile使用,内存优化,包大小优化

游戏优化往往是游戏开发中比较重要的一个环节,下面就分享一些自己在性能优化,内存优化,包大小优化方面的经验和总结. Profiler 是unity自带的,用来分析游戏运行性能,内存使用等非常好的工具,你可以通过它准确定位到影响游戏性能的脚本方法,内存过高的资源等等,对你优化游戏性能,内存有很大的帮助. 一.cpu占用分析 可以看出在白色竖线定位的那一帧,Game.Update()占用了88.3%,如果想知道脚本具体调用堆栈,和具体的问题出在哪,需要把Deep Profiler选上进行深度分析,当你

李洪强iOS开发之性能优化技巧

李洪强iOS开发之性能优化技巧 通过静态 Analyze 工具,以及运行时 Profile 工具分析性能瓶颈,并进行性能优化.结合本人在开发中遇到的问题,可以从以下几个方面进行性能优化. 一.view优化 1.不透明的View 设置为opaque. 2.根据实际情况重用.延迟加载或预加载View. 3.减少subviews数量,定制复杂cell使用drawRect.尽量使用drawRect而不是layoutSubView. 4.不直接调用drawRect. layoutSubviews方法.万不

检测SDWebImage有没有缓存图片 IOS 获取网络图片大小

NSURL *url = [NSURL URLWithString:[model.content objectForKey:@"image"]];             //请求网络地址数据的同步方法             //因为这个方法在子线程(全局队列)中执行,所以不需要考虑死线程的问题             SDWebImageManager *manager = [SDWebImageManager sharedManager];              [manag

Unity与iOS原生代码之间的相互调用

效果: 代码: [GitHub]Unity_iOS_Plugin_Demo 关键: 1.Unity调用iOS: 1.1.在Unity C#中: [ DllImport( "__Internal" )] private static extern int _showSelectTitleDialog ( string title, string msg); 1.2.在Xcode Objective-C中: extern "C" { int _showSelectTit

Unity导出iOS真机测试教程

原地址:http://unity3d.9tech.cn/news/2014/0410/40177.html 学 习了两天的Android开发,我感觉Android开发跟IOS开发和.NET平台下的开发有点不同,Android开发我更觉得跟web(Html) 倒是有类似的地方,都是节点标签显示的,当然个人理解,感觉提示也没IOS开以及.NET开发那么强,可能是我还不是太熟悉eclipse开发环境,当然 当做出东西能导入到自己的Android机还是挺兴奋的.今天晚上摸索了一下IOS真机测试,手上有M

复杂TableView在iOS上的性能优化

声明:本文翻译自<iOS performance optimization>,原文作者 Khang Vo.翻译本文纯属为了技术交流的目的,并不具有任何的商业性质,也不得利用本文内容进行商业盈利.欢迎转载,但是希望转载的时候加上出处连接,谢谢.译者联系方式 [email protected],如果有 iOS 开发之类的问题,欢迎?一起讨论,谢谢.另,由于本人翻译经验不多,如果翻译不妥或者理解不到位的地方,希望各位朋友海涵,可以发信到上述邮箱,我会及时地根据大家的反馈,对翻译稿做及时地修改,谢谢!

unity与iOS、Android交互

1.Unity调iOS的方法 在首页的viewcontroller里面实现方法 void _PressButton3(const char *args) { //  UnityAppController *unityapp = (UnityAppController *)[UIApplication sharedApplication].delegate; // [unityapp ShowWindowssubview]; } 在Unity里面 直接调用 _PressButton3(conten

unity与ios交替

unity和ios的相互作用是更简单的.直接出口xcodeproject,这个大家都知道如何操作,如果需要二次开发ios码成unity,事实上,整合非常easy找到出口xcodeproject内iPhone_View.mm中间OnUnityReady()方法.unityios中一个view,[GetAppController()showGameUI:_mainDisplay->window];载入游戏视图,这种方法在UnityAppController中,- (void)showGameUI:(

unity导出iOS所遇到的问题

现在的公司要做AR教育类的app,所以需要用到unity那边的代码,但unity那边导出iOS后,运行xcode会各种报错,千奇百怪,我只说下我自己遇到的问题以及解决方式 unity导iOS不要在window上导,不然怎么弄都会报错,把unity开发那边给的包拿到mac版的unity上导出来 我用的是unity5.3和xcode7.3 先说下导出iOS的步骤   先把包直接拖进unity里  然后build settings 把要运行的环境拖进去 然后选iOS  再点switch platfor