当前位置: 首页 > 科技观察

一个BUG的发现、定位和解决

时间:2023-03-16 01:40:30 科技观察

前言iOS11发布后,出现了一系列适配相关的问题。pagingEnabled=YES时UIScrollView的滑动手势不灵敏、UITableView的滑动删除功能发生变化、UIImagePickerViewController的取消按钮点击区域变小等。本文介绍其中一个UIAlertView问题,分享其发现、定位及解决方案。文1.iOS11正式版发布后不久就出现了这个问题。测试同学提到一个iOS11相关的bug,表现是:在直播间发聊天消息,如果被ban了,会弹出“BackedForbidden”提示,键盘缩回,然后无法开发者收到这个BUG时,首先抽象出了问题的几个要素:在直播间,键盘弹出,弹出提示,键盘缩回,键盘无法弹出。-up提示在UIAlertView的方式中使用,当键盘出现时弹出UIAlertView提示,键盘会收起,UIAlertView消失后,键盘会再次弹出,属于正常表现。2.问题复现尝试按照复现路径,发现bug可以复现,确认问题存在;根据经验猜测问题可能出现在键盘和UIAlertView上,与“静音”业务无关.试试其他非“禁”直播间里的场景。当键盘出现时,会弹出UIAlertView提示,也会导致后续的键盘无法弹出。在尝试了其他非直播间的主场景后,问题可以描述为:iOS11机器只需要弹出一次UIAlertView,之后就无法通过becomeFirstResponder调用键盘;输入区域必须手动点击才能触发系统的键盘弹出行为,或者切换到后台再切换回来,这样键盘才会正常弹出。在某些页面点击评论后,会添加一层透明的maskView,并弹出键盘。点击透明maskView会调用resignFirstResponder消除键盘消失通知中的maskView。因为无法弹出键盘(也无法收到键盘消失的通知,但maskView还是正常添加的),这部分页面无法进行后续交互。3.问题评估重现问题后,需要评估问题的严重程度,确定BUG修复的优先级。从已知性能来看,在iOS11下使用影响更大(UIAlertView提示更多)。我用iOS11机器下载外部版本测试,发现bug无法复现!虽然很奇怪,但是可以降低问题的优先级,放在正常的BUG解决列表中。4.问题分析外部版本是Xcode8编译的,本地版本是Xcode9GM编译的。是Xcode9编译造成的吗?新建一个只有输入框和按钮的demo,模拟UIAlertView弹窗,发现demo正常;将app的工程设置复制到demo中,输入框的属性设置也复制到demo中,demo还是正常的;将demo代码复制到app中,将app的rootViewController赋值给demo中的VC,依然正常;可以确定是app部分代码导致无法弹出键盘。二分注解后,很快(4、5次)定位到问题出在app中的某个Service类。仔细整理Service类的属性,发现有一个属性继承自UIWindow,级别比UIWindowLevelStatusBar高。从那以后,根据我们所了解的和Apple的UIKit文档,我们可以对问题进行回溯。5、问题回到苹果官网对响应链和UIWindow的描述。其中关于becomeFirstResponder()的解释是:要求UIKit使该对象成为其窗口中的第一响应者。关于UIAlertView的iOS11系统行为,猜测:UIAlertView中的弹窗,此时会抢占系统的keyWindow,所以键盘会在UIAlertView中收回(因为keyWindow发生了变化);当UIAlertView消失后,会遍历所有Window,找到z轴***作为keyWindow,所以键盘会出现在UIAlertView消失后弹出(keyWindow变成原来的);通过编写代码调试app,证实了上述猜测。在iOS11中,如果UIAlertView弹出时有windowLevel大于UIWindowLevelNormal的UIWindow,会触发无法弹出键盘的bug。6.Bug修复确保应用中没有常驻的UIWindow;修复无法弹出键盘时maskView无法消除的bug;UIAlertView将在后续版本中被替换;总结问题从产生、复发、定位、评价到修复的时间与写这篇文章的时间差不多。BUG解决流程不同,所以提醒自己解决BUG要有目的和优先级。