上周项目上线后出现一个奇怪的线上崩溃问题,写篇文章记录一下。
问题
系统为iOS9.0.2、iOS9.1、iOS9.2、iOS9.2.1的iPhone,通过App Store下载的,一启动程序就会闪退,但是在模拟器上或者真机debug模式相同系统版本的情况下也不会闪退。我们的项目环境为:Xcode9、Objective-C、Target iOS8.0及以上。
日志
下面列举几个常见的日志:
1、UIKit: -[UINibStringIDTable lookupKey:identifier:] + 132
UIKit: -[UINibStringIDTable lookupKey:identifier:] + 132
2、UIKit: UINibDecoderDecodeObjectForValue + 788
UIKit: UINibDecoderDecodeObjectForValue + 788
3、CoreUI: -[CUIStructuredThemeStore renditionWithKey:usingKeySignature:] + 1600
CoreUI: -[CUIStructuredThemeStore renditionWithKey:usingKeySignature:] + 1600
4、libcache.dylib: _entry_get_optionally_checking_collisions + 164
libcache.dylib: _entry_get_optionally_checking_collisions + 164
5、FrontBoardServices: -[FBSSerialQueue _performNext] + 192
FrontBoardServices: -[FBSSerialQueue _performNext] + 192
6、QuartzCore: CA::Context::commit_transaction(CA::Transaction*) + 340
QuartzCore: CA::Context::commit_transaction(CA::Transaction*) + 340
解决
经网上查阅资料,发现Apple Developer Forums 上有一个跟我们近乎一样的问题(Crashes on iOS 9.0.2, 9.2 and 9.2.1)线上IPA包的图片资源中有3张图片的DisplayGamut是P3形式的(kCGColorSpaceDisplayP3是iOS9.3及以后才支持)。按如下几步操作即可解决:
1、导出线上IPA包,找到其中的Assets.car文件。
2、利用assetutil命令行工具将Assets.car文件导出为json格式,在终端进入Assets.car文件所在的文件夹下输入以下命令:
sudo xcrun --sdk iphoneos assetutil --info Assets.car > Assets.json
3、打开第二步生成的Assets.json文件,查找DisplayGamut或者ARGB-16,包含此类信息的图片就是这次闪退问题的罪魁祸首了。替换一下对应的图片重新打包发布即可。
尾声
虽然及时解决了这个崩溃问题,但是今天回头又看了下,发现网上有个类似的问题(Release版本只在iOS9.2及以下闪退),对比了下,又稍微有些区别——原博主的是显示的图片格式问题,而我们项目中的却不是。PS:原博文介绍了另一种通过脚本处理所有图片格式的方法,本文就不列出了。我们有三张问题图片:
但是在Xcode中查看Color Space是正常的,如下所示:
然后对比了正常图片的Color Space也是sRGB IEC61966-2.1。因此,给本人带来一个疑惑,有待进一步证实~
补充说明
国庆假后得知业出现了很多类似问题,不过是Xcode10的bug,Apple也给出了回应,Xcode10.1会解决这个bug。
解决方案可以参考高老师很忙的微博: 解决Xcode10打包iOS9.0-iOS9.2.1Crash的问题
参考资料
[1]、Crashes on iOS 9.0.2, 9.2 and 9.2.1
[2]、App crashes as release build on iPad/iPhone 6-iOS 9.2 - but debugging is fine
[3]、App crashes immediately on start up… Crash in iOS9 on release only through TestFlight or Store. Distributed with Xcode 8
[4]、Release版本只在iOS9.2及以下闪退