Swift工程混编PgyUpdate升级SDK闪退问题

0.背景描述

之前有一个小项目是用Swift开发的,因为是公司内部人员使用,所以只是使用企业证书签名,在蒲公英网站上进行发布。所以,升级功能也是直接使用的蒲公英官方的SDK——PgyUpdate。
上个月项目新增一个需求,改了埋点统计的字段,其他代码没动,但是开发完成后,新打的测试包却出现启动闪退的问题。

1.问题查找

1.1.定位

经过初步调试排查,发现断点报错信息为:
Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)
而闪退问题出现在
PgyUpdateManager.sharedPgy().checkUpdate(withDelegete: self, selector: #selector(self.updateMethod(_:)))这句代码执行之后,但并没有进入这里指定的回调方法。
所以怀疑是PgyUpdate的SDK出现空指针异常。随后我又用干净Demo验证了该问题,发现可以重现,所以就给蒲公英官方提了工单,并上传了Demo代码以及我使用的appid、appkey。

1.2.规律

在等待官方处理工单的时候,我又想起线上的包会不会有类似的问题?但一直没人反映,应该是不会的。我下载线上包运行,果然不会闪退。随后我发现了规律:
当工程版本<蒲公英平台上最新版本时,不会闪退;
当工程版本=蒲公英平台上最新版本时,会闪退;
当工程版本>蒲公英平台上最新版本时,会闪退。

这就让我吐血了,因为线上应用的版本和蒲公英平台上的版本肯定是相等的,但却不会闪退。
因此加倍确定是sdk中存在逻辑错误。

1.3.排查

随后蒲公英技术支持人员联系我,看了我的调用代码,并发给我一个测试sdk包。
我测试之后发现当工程版本=蒲公英平台上最新版本时,会闪退已经没有了,我一度以为BUG已经改好了,但是不久发现当工程版本>蒲公英平台上最新版本时,会闪退还是存在。
继续排查,支持人员发现sdk在调用回调方法func updateMethod(_ response: Any) {}时会闪退,因为传入的参数response为nil。
但是,和之前运行正常的版本相比,sdk代码和我的业务代码都没有改过,唯一动过的就是蒲公英后台的代码(他们最近做了升级)。

2.问题原因

至此问题原因就明白无疑了,因为蒲公英后台的变动,在SDK调用checkUpdate方法检查更新时,若没有新版本,原来的后台会至少返回一个空对象;但是现在的后台,直接返回了nil。
所以在查找问题的过程中我们就发现SDK方觉得自己代码没有问题,而业务方也觉得自己代码没有问题——因为双方调试运行时都无法进入闪退的断点。

那出错的点在哪儿呢?
出错的地方在于func updateMethod(_ response: Any) {}回调方法的声明中,参数response的类型是Any,Any表示是非可选类型,必定有值的,所以系统在桥接Swift和OC代码时就会强制把nil值转换成非可选类型,从而导致闪退,出现一个系统异常EXC_BAD_ACCESS

3.解决方法

该问题的解决方法也非常简单,只需要将回调方法中参数response的类型声明为Any?可选类型即可。

4.未解之谜

问题已经完满解决,但是问题原因却还有不通之处,因为最初我在demo中验证的其中一个问题场景当工程版本=蒲公英平台上最新版本时,会闪退;无法解释?
这个问题在demo中可以重现,但是线上的安装包却又没有这样的问题。
中间我一度怀疑是debug模式和archive模式打包编译的原因,但后来一想,我的测试包也都是使用archive模式打出来的,也同样会闪退,所以还是解释不通。
或许这是编程界的又一个玄学之谜吧……

猜你喜欢

转载自blog.csdn.net/jhq1990/article/details/80572972