关于问题
上述的图片就是我们本次的 Crash 问题,这个问题目前在作者这个版本100%复现。
复现的操作就是关闭 ARC,关于ARC的解释下文会说到。
关于这个问题,我度娘,GG都翻了一遍,没有任何有用的信息,而且资料少之又少,类似的资料就是关于AirPlay的闪退,但是和这个问题似乎关系不大,所以初步怀疑是Unity 在某个版本升级后,部分库,或者部分C++文件包含了ARC的东西,或者使用ARC方式编写了某块代码,导致内存的损害(没有释放内存/重复释放内存),关于这个问题,可能从某个Unity版本开始,具体是哪个版本,可能就需要各位遇到问题的,并且通过本文解决了问题,请留下你的Unity 版本,以及Xcode版本,告诉我。
我们先去了解下ARC。
关于ARC
这里简单说明下,这个ARC是在Xcode4.x 某个版本就支持的东西,它是自动帮我们管理内存的释放等 (release autorelease, retain,…) 据官方的说明 可以增加性能,可以解决大部分 EXC_BAD_ACCESS(内存操作损害) 造成的闪退问题。
当前工程 开启/关闭 ARC 方式:Build Settings -> Apple Clang - Language - Objective-C -> Objective-C Automatic Reference Counting (Yes / No)
PS:当开启了ARC模式 (release autorelease, retain,…) 等操作就会报错。
局部文件编译开启和关闭ARC Flags 开启关闭方式:Build Phases -> Compile Sources ->(这里面 Complier Flags 添加关闭/开启 相关的 Flags)
- 在工程开启ARC模式下,所有的文件编译都会默认 ARC,局部文件关闭ARC Flags 为 :-fno-objc-arc
- 在工程关闭ARC模式下,所有的文件编译都会默认 MRC,局部文件开启ARC Flags 为 :-fobjc-arc (或者好像是 -f-objc-arc)
ARC 的原理大致说明了下,总归两点:自动释放内存和提升性能(其它没深入)
当我们出现本文的 Crash 时,我的解决思路是这样的:
- 首先我们使用Unity 创建并且导出一个全新的工程(没有任何污染的工程)
- 记录全新 Xcode 工程的所有默认配置(因为 Unity导出的全新工程总是能编译和调试)
- 把第三方库(Freamworks)分量的拷贝进去全新的工程,看看是否是库导致的闪退。
- 如果不是第三方库引起的 Crash,那么我们尝试修改 Xcode 配置(因为在我们最终编译通过时,工程配置总是会被污染)
一般3-4点总能找到问题的所在,当然你也可以获取调试的 Crash Logs 来辅助你,不过这不在本文范涛,不做讲述。
PS:第三步和第四步可以并行的查找和调试。
最终本文的问题是定位到第四步,也就是我们的ARC,Unity导出的Xcode默认工程是开启ARC,而因为我的某些库存在MRC的编译,所以我需要关闭ARC,我偷懒,就整个工程都关闭了,能编译通过,但是就造成了本文开头的问题。
至此,问题解决,顺便总结了一点:默认工程任何的配置和默认的修改都是有意义的,在不是极端的情况下,请保持配置。