https://support.unity3d.com/hc/zh-cn/articles/208412186-IL2CPP-%E6%9E%84%E5%BB%BA%E5%A4%A7%E5%B0%8F%E4%BC%98%E5%8C%96

问题

  • 应用大小超过 iOS 移动网络下载的限制会强制 iOS 用户通过 WiFi 下载。
  • 应用的通用安装包或者单独包均大于苹果提交指引的要求。

原因

我的应用大小超过了 iOS 移动网络下载的限制并且超过了 tvOS 主应用的大小。

otool的报告反馈单独的应用包(32bit, 64bit)或者是通用包都超过了苹果提交审核的要求。

解决方案

IL2CPP将C#的预编代码转换C++代码,这些代码将会被Xcode和LLVM转换成最终的执行代码,这会导致更大的通用包或者应用分片(32bit,64bit)尺寸。您可以通过几个方面来优化代码。阅读下面的信息将更有助您了解可以做哪些工作来优化构建包的大小:

为什么 IL2CPP 编译的包要比 mono 的大呢?

有两方面的原因:

  • 如果您使用的是通用构建,那将会有32bit分片和64bit分片两个部分,而这两个部分为两种不同的架构包含了两个完全一样的可执行文件,导致尺寸增大一倍。
  • 如果您对比过ARMv7 Mono 和ARMv7 IL2CPP的话,IL2CPP的版本会更大些;造成这样是因为要处理类型的元数据。这在Unity 4.6.4p2中已被修复。在4.7.0f1和5.4.0f1中都做了进一步的改进。

相比于只针对ARMv7或者ARM64架构,针对通用架构进行构建总会生成更大尺寸的包。移除托管组件集已经可以使构建更小(Unity 4.6.3f1), 但是真正的改进来自于我们在运行时中可以至少创建通用的typeinfo (generic typeinfo),不过这个功能目前在Unity 4.6.4p1中已经可以部分实现了。 相比于Mono 32bit,包含了32-bit分片和64-bit 分片的通用构建尺寸要大上一倍 。

在 Unity 4.6.4p1,我们改进了通用类型和数组类型。除此之外,这里有减小 iOS 包体大小的信息。额外的信息可以读下面的与Stripping相关的章节。

请在mono (ARMv7), IL2CPP (ARMv7), IL2CPP (ARM64), IL2CPP Universal之间做个对比表格,包括使用了哪些Stripping设置的信息!

关注当前二进制包的大小是很有必要的,因为如果这是一个通用构建,由于包含了ARMv7和ARM64的包,导致相比于单个ARMv7 mono或者IL2CPP的包要大上一倍。如果您想拿输出做直接对比,那么请拿 ARMv7 mono 和 ARMv7 IL2CPP做对比。

 

苹果会检查哪些大小的限制?

请点击这里查阅查苹果应用商店的提交信息。

  • 对于MinimumOSVersion 小于0 的应用, 二进制包__TEXT 部分最大是80MB。
  • 对于MinimumOSVersion 是x 到8.x 的应用, 二进制包中每种架构__TEXT 部分最大是60MB。
  • 对于MinimumOSVersion 是x 或者更高的应用, Mach-O 二进制包中最大是400 MB。

如果您支持的iOS系统小于iOS 7.0, 苹果对于32bit+64bit代码部分一共有 80MB 的大小限制。对于iOS系统版本最小是7.0或者更高的,针对每个架构的分片有60MB(60 000 000 字节)的大小限制。100MB(移动数据)应用限制(用户需要通过 WiFi 下载)和最大 4GB 的应用限制。 80MB 和 60MB/60MB是针对包含在fat二进制里的32bit和64bit分片的大小限制。您需要用otool以获得准确的数字。.ipa 文件的大小限制在100MB,这个大小决定了用户是否需要通过 WiFi去下载您的应用。通过以下这些步骤以获得准确的数字:

  1. 在发布模式下构建您的应用。不要用测试模式,因为它无法代表您的最终安装包。确认您使用了正确的优化方法,可以点击此处了解更多信息:http://docs.unity3d.com/Manual/iphone-playerSizeOptimization.html。

  2. 在 XCode 下打包您的应用,并用您的部署证书导出.ipa文件。

  3. 使用估算按钮来估算应用的大小,以确认应用小于100MB或者整体包的大小小于4GB。

    注意:从 Xcode 6.3起就没有估算按钮 了。您可以通过以下公式计算大小,但是要注意压缩系数可能会有所变化:
    app_store_size = sizeof(.ipa/(zip with exec_binary removed)) + sizeof(codesegment(exec_binary)) + 0.2 * sizeof(datasegment(exec_binary))

    该公式是基于以下的认知:只有代码部分(code segment)会被加密,数据部分(data segment)的压缩率可以很容易被确认 。

    使用dd命令从可执行包里面解压出数据 (你可以指定字节偏移和长度),然后再压缩这些数据。代码部分(code segment)被加密成完美的噪声一样。在执行之前你需要一个密钥才能反编译它。iTunes/App Store管理着这些密钥。这就是为什么我们被代码部分(code segment)看做一个整体,而没有将它包含在压缩率的计算里面。

  4. 当您创建好 .ipa包以后(包体的大小几乎等同于Xcode估计按钮返回的结果),打开终端,找到.ipa的 目录,然后运行otool。

  5. 使用otool将输出进行解压缩,然后查看是否已经接近80MB的大小限制 。

    otool -l <your_app_name>.app/<your_app_name> or size <your_app_name>.app/<your_app_name>

  6. 现在您可以根据不同的架构得到相应的输出(如果是通用架构,则是armv7 + arm64 两部分 ),为armv7 (LC_SEGMENT)收集信息,如果arm64 (LC_SEGMENT_64) 可用的话,你可以做同样的事情。

    1. 用segname __TEXT定位到LC_SEGMENT

      code segment size = 30474240 ~= 30MB

    2. 用segname __DATA定位到 LC_SEGMENT
      data segment size (mostly metadata) = 10420224 ~= 10 MB

    otool返回的结果如下:

    armv7架构:
    code segment size = 30474240 ~= 30MB
    data segment size (大部分是元数据) = 10420224 ~= 10 MB
    segment + data segment = 30 + 10 = 40MB

    arm64架构:
    code segment size = 25559040 ~= 26MB
    data segment size (大部分是元数据) = 17727488 ~= 18 MB
    segment + data segment = 26 + 18 = 44MB

    苹果使用这个例子中的otool报告(30MB + 26MB = 56MB)来做检测。上述报告在 <7.0的时候,小于80MB;在>=7.0的时候分别是30MB和26MB,两者都是小于60MB。

在这些检查的基础之上,就很容易在发布模式下打包一个测试应用,然后提交给iTunes Connect。在提交过程中,如果分片大小超过限制的话,静态项目检查器应该会提醒您。一旦您把应用提交到iTunes Connect,您就可以看到针对所有单个平台和通用平台苹果所期望的压缩后文件大小,下载文件大小和安装文件大小。可以看下面的例子:

使用 iOS 9.0的设备会根据需要只下载相应的部分(32或者64)。苹果会切割这些二进制包并会创建一个独立的包,所以像iPhone 6s这样的设备会得到一个更小的下载包,这个过程中你不需要做任何事情。这跟 ODR 或者 Bitcode 完全没有关系。但是使用 iOS 9.0以下的设备仍然需要下载通用包。

剥离

不管在Unity的Stripping Level 配置如何设置,IL2CPP的脚本后台还是会做字节代码的拆解。对于用户来说最好的选择就是把Stripping Level 选项设置为禁用,因为IL2CPP总是会做拆解,所以 拆解层级对于执行包的大小影响其实很有限。如果你打开了Stripping Level的设置而不是选择禁用,您可能会遇到一些问题,因为IL2CPP编译工具链会尝试去了解您的脚本集合使用的是哪些原生引擎代码,导致在应用启动时只注册相关的原生代码。如果您在使用拆解设置的时候遇到问题,并且觉得他们是有问题的,请提交bug报告给我们。

5.3.x由于 Bitcode 的原因构建的大小会变大

当您用 Unity 5.3.x 构建iOS应用的时候,得到的包体会变大。这是因为 5.3.x的 Bitcode 支持已经打开了。为什么这是件好事以及怎么处理可以看这里。

通过 MapFileParser 分析脚本

您可以更深入地了解和查看脚本对包体大小的影响。您可以使用 MapFileParser 这个来检查可执行文件的尺寸以及脚本对其大小所做的贡献。这个工具会在Xcode打包应用的时候,处理Xcode生成的map文件(在使用Archive打包的时候不会生成map文件) 。在 5.2.4p1 及以下版本里,-stats 这个标识符是不存在的。您可以在 Unity.app 的安装目录下找到 MapFileParser 或者Unity生成的 Xcode 工程根目录中也可以找到。在 Xcode 链接输出的Derive Data文件夹中可以找到 your_map_file.map。

完整的路径类似于:Library/Developer/Xcode/DerivedData/Unity-iPhone-glmxdxebssyebsfcbtobeuasetge/Build/Intermediates/Unity-iPhone.build/<mode>-iphoneos/Unity-iPhone.build/alpin-LinkMap-normal-<architecture>.txt

您可以在终端运行下面的命令来分析这些map文件。

<Contents/Tools/MapFileParser/>MapFileParser -format=Clang <your_map_file.map> -stats

分析这些函数的名字是区分不同代码最好的方法(用户脚本,静态库)。从托管集里面生成的代码会以 _m的后缀结尾。例如:

_TestScript_Start_m4164746442: 10 bytes
_TestScript_Update_m263972995: 10 bytes
_TestScript
_ctor_m922641354: 24 bytes

这会帮您更好的理解您的代码,插件或者引擎代码。

更多信息

  • 关于优化iOS及tvOS应用大小和IL2CPP
  • 关于IL2CPP的信息
  • 关于IL2CPP的博文

  • 关于iOS 64bit的支持

  • 关于IL2CPP构建大小的改进

本文适用于 Unity 5.2.0p1 及以上,Xcode7及以上,iOS9.0及以上版本

IL2CPP 构建大小优化相关推荐

  1. Flutter framework在线上构建时的包大小优化

    混合开发线上构建之flutter包大小优化 前景 打包flutter flutter引擎包的来源 缩减fluter framework大小 总结 前景 因为项目要使用jenkins线上构建,所以整个项 ...

  2. webpack打包优化_提速MAX 京东通天塔WEBPACK构建发布优化实践

    通天塔作为运营.商家搭建营销活动页的主力系统,数年来一直致力于提供用户更丰富.更强大的搭建体验.通天塔可视化CMS(简称可视化)作为直面商家运营搭建的第一层,在系统能力越来越强大的同时,自身的代码量. ...

  3. Android 包大小优化总结

    Android 包大小优化总结 众所周知,尽量减少 APP 安装包的大小是非常必要的,减少安装包大小,不仅减少了用户下载时的网络流量消耗,而且还减少了用户的下载等待时间.更重要的是安装包大小也会影响下 ...

  4. Gradle 构建速度优化

    构建速度优化 AS编译太慢是我们经常吐槽的,我们该做些什么来加快编译的速度呢?前面我们简单的了解了gradle构建项目的流程.我们可以从以下几个方面来做: 注意AS配置: 如及时更新Gradle和JD ...

  5. docker(四)镜像的大小优化

    镜像的大小优化与默认挂载 一.优化镜像 优化一:把不需要的命令丢入/dev/null 优化二:减少RUN构建 优化三:多阶段构建 优化四:使用更为轻量级的linux发行版 二.关于VOLUME 一.优 ...

  6. 优酷 Android 构建速度优化实践

    作者:苏彦郊(木磊) Android 项目一般使用 gradle 作为构建打包工具,gradle 简洁.动态的功能特性为人津津乐道,同样,构建执行速度缓慢的缺陷也一直为人诟病. 近年来,随着优酷功能特 ...

  7. 今日头条 iOS 安装包大小优化 - 新阶段、新实践

    前言 今日头条 iOS 端从 2016 年起就关注到了安装包大小的问题,并启动了包大小优化.2017 年,我们将当时的经验发表为技术文章 <干货|今日头条iOS端安装包大小优化-思路与实践> ...

  8. 工程大小优化之图片资源

    工程大小优化之图片资源 摘要:点点iOS项目本身功能较多,导致应用体积也比较大.一个Xcode工程下图片资源占用了很大的空间,且如果有些App需要一键换肤功能,呵呵,不知道得做多少图片.每套图片还需要 ...

  9. 《机器学习》课程视频(数据处理、模型构建与优化)

    一直以来我经常听到很多粉丝反馈,觉得人工智能是目前最牛X的技术,想要尝试自学入行,将自己的一些想法和创意付诸现实. 但大部分人苦于不知从何入手,往往抓不到学习重点.或是止步于晦涩难懂的理论和烧脑的算法 ...

最新文章

  1. 100多篇论文被知网擅自收录!89岁教授维权获赔70余万!
  2. System.arraycopy
  3. GDI+ 学习记录(2) 画笔线帽 - Cap
  4. 二分查找非递归方式实现
  5. UVA 514——Rails
  6. 67 cookie常用方法
  7. 《数学分析》里的人生
  8. iphone:MKMapView
  9. Redis之GeoHash
  10. jQuery插件Label Effect制作个性化的文字特效
  11. python时间比较好_花了半个月时间,终于找到了一款最适合的python教程
  12. easyui弹出窗关闭前调用确认窗口,先关闭页面后调用弹出窗口
  13. 数据交互什么意思_学习编程怎么样才可以不枯燥?什么是前端语言?
  14. SCI论文下载之chrome插件
  15. SAP 报表设计器相关TCODE
  16. 计算机重新启动操作处于挂起状态,PHOTOSHOPCS5安装程序检测到计算机重新启动操作可能处于挂起状态...
  17. 数据结构 队列的结构特点及基本操作
  18. sensor曝光量和曝光行的区别_如何理解 ISO、快门、光圈、曝光这几个概念?
  19. 快速解决“多分类不平衡”问题
  20. 【UOJ 454】打雪仗(通信题)(分块)

热门文章

  1. 【数据结构】开端序幕
  2. 更改netbios计算机名,修改你计算机的Netbios名
  3. 网络安全兼职注意事项
  4. 最小生成树算法-克鲁斯卡尔和普利姆
  5. mysql--部门表员工表练习题
  6. 运营 | 做自媒体应该从哪方面入手?
  7. C#中indexof和substring函数用法 (截取字符串)
  8. 利用Joypy绘制嵴线图的案例
  9. 农村信用社改革试点专项借款管理办法(银发[2003]181号)
  10. 哇!8款帮你轻松瘦脸的美食