如何快速定位、分析、解决非Crash的BUG

发表于:2018-1-15 13:27

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:落影loyinglin    来源:简书

  前言
  众所周知,Bug是线上应用极力规避但又无法避免的。对于致命的Bug,我们可以通过Crash日志进行分析;对于无法复现的Bug、特定操作步骤引起的Bug、某些版本/系统才出现的Bug,每个开发者都有自己的一套分析、定位、解决的方法。
  本文以工作中遇到的几个iOS 11 Bug为例,介绍快速定位、分析、解决Bug的经验。
  正文
  iOS 11裁剪图片偏移问题
  功能背景:
  用户从本地相册选择图片,然后裁剪一个正方形区域,最后生成用户头像。
  Bug描述:
  iOS 11的iPhone X,选择本地图片,然后进行裁剪,生成的图片有明显的偏移,如下:
  功能实现:
  裁剪控件是系统提供的UIImagePickerController。
  Bug定位:
  用模拟器进行复现,并断点在UIImagePickerController的回调方法,再用Xcode查看实际的返回参数和图片。
  如下:
  ①是特意选择的区域,刚好覆盖到瀑布的顶部;
  ②是UIImagePickerController的返回参数,通过po命令查看;
  ③是按照返回参数的CropRect在原图截取出来的区域;
  ④是返回参数中的图片;
  经过可以对比发现,③和④的图片是一致的,并且明显与①所选中的区域有所偏移。以同样的方式尝试iPhone X和6s的模拟器,发现都有偏移现象,且iPhone X的偏移更为严重。
  检查本地代码,确认是正常的方式调用UIImagePickerController,那具体是哪一步影响裁剪结果呢?
  仔细体验UIImagePickerController的裁剪功能,发现一个可疑的现象:
  底部始终无法选择!
  6s模拟器,蓝色箭头指向的区域是无法选择的!
  以这个区域为突破口,对比此处区域的高度值和裁剪的偏移值,得到大致是1:2的比例,符合2x屏幕。
  用iPhone X模拟器同样复现了这个问题,并且不能选择的区域更大。
  而且非常有意思的是:iPhone X模拟器的裁剪偏移量为44pixel。
  对于做过iPhone X适配的开发,对于44这个数值域是非常敏感的(顶部安全区域的高度),猜测是和statusBar有关。
  再找到6s的模拟器对比裁剪偏移量,果不其然,大致是22pixel。
  至此,Bug摸清来龙去脉:
  UIImagePickerController的裁剪选择视图向下偏移了status bar的高度,但是裁剪的时候还是按照y=0计算,导致结果产生偏移。(猜测是iOS 11 UIScrollView的contentInsetAdjustmentBehavior属性导致)
  Bug解决:
  裁剪时,隐藏statusBar。
  PS:此Bug在iOS8也会出现,iOS 9/10是正常的。
  iOS 8隐藏statusBar需要在UIImagePickerController的delegate实现中,添加以下代码
  - (void)navigationController:(UINavigationController *)navigationController
  willShowViewController:(UIViewController *)viewController
  animated:(BOOL)animated {
  if ([navigationController isKindOfClass:[UIImagePickerController class]] ) {
  [[UIApplication sharedApplication] setStatusBarHidden:YES];
  }
  }
  修复后,可以正常选择底部
  小结:
  善用工具,快速定位。
  对于能够复现的Bug,Xcode连接真机断点调试是最方便的方法。
  但是切记,不要沉浸在单步调试和盲目枚举尝试的过程。
  iOS 11图像放大闪烁问题
  功能背景:
  用户点击圆形头像后,头像会放大到等同屏幕宽度,并且从圆形展示变成正方形展示。
  Bug描述:
  iOS 11的iPhone 7p,在点击头像之后,在头像放大的过程中会有闪烁的现象。(iPhone X效果最为严重,除了闪烁还有抖动现象)
  功能实现:
  圆角按钮通过layer.cornerRadius实现,头像放大是UIView的animation block动画;
  Bug定位:
  先用模拟器进行尝试,发现无法复现;再用真机进行测试,发现偶然会闪烁的现象。
  用录屏工具辅助,定位到闪烁是因为图片放大的动画过程中,出现了某一帧异常:
  
异常帧1
  
异常帧2
  上面的展示效果类似OpenGL纹理展示的GL_CLAMP_TO_EDGE模式,怀疑是图像放大过程中的边界处理有异常。
  带着疑问回看代码。查看头像详情时,点击头像(为圆形)会全屏显示头像大图。整个过程的动画内容包括两个:
  1、imageView的frame变成覆盖整个屏幕;
  2、imageView的layer.cornerRadius变成0;
  以上的代码,在iOS 10下没有闪烁问题,但是iOS 11就会出现这个异常。
  遇到代码不同iOS版本的表现不同时,先查一下API的变动。
  查看苹果的文档后发现,layer的cornerRadius属性在iOS 11之前是不支持Block动画的。iOS 11之后新增了cornerRadius属性的Block动画支持,但是明显支持效果不是很好。
  Bug解决:
  解决方案1:移除动画过程中cornerRadius的属性变化;
  解决方案2:统一用CoreAnimation来实现;
  小结:
  模拟器先行,真机验证。
  模拟器具备多开的优势,可以同时打开多个系统的多个设备;但是因为模拟器的cpu架构与真机不同,最终必须用真机验证。
  文档为主,Google为辅。
  iOS版本升级经常引入Bug,对于这种不同iOS系统导致的问题,需要查看文档(文档包括Xcode的头文件以及自带的文档),如果文档找不到则用Google查找对应的关键词。
  iOS 11动画异常问题
  功能背景:
  正常的动画效果,比如微信的聊天图片放大动画和手Q的头像放大动画,如下图:
  
iOS 11 微信.gif
  
iOS 11 QQ.gif
上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号