【团队分享】手机QQ:升级iOS8.3后,发图就崩,为哪般?

向华,手机QQ项目团队,高级移动开发工程师,座右铭:Be The Best!

4月9号,苹果开始向iOS用户推送最新系统版本iOS8.3的升级。手机QQ团队第一时间进行系统升级的兼容性验证,发现在图片选择器界面切换标清图和原图时必现闪退现象。同时,在微博、论坛和support平台等渠道均有收到大量用户反馈此问题。 于是,我们迅速在厂内的崩溃统计分析平台(小编注: 即Bugly平台)查找相应崩溃问题的堆栈信息进行分析。

初步分析发现崩溃问题定位在UIView addSubview的调用,并有明确的错误信息:

Terminating app due to uncaught exception 'UIApplicationInvalidInterfaceOrientation', reason: 'Supported
 orientations has no common orientation with the application, and
 [QQMarkActionSheetController_FixPos shouldAutorotate] is returning
 YES'

我们进行了真机联调测试,验证崩溃问题必现场景同崩溃分析平台记录的一致。

再分析崩溃信息的详情,可以明确崩溃问题是由于QQMarkActionSheetController_FixPos的方向和application的方向不一致导致的。

于是,按照如下方法修复此问题:

  1. 查找源码定位QQMarkActionSheetController_FixPos继承自UIAlertController
  2. 重写shouldAutorotate方法,返回值设为NO

重新编译调式验证,崩溃问题果然解决。

但正所谓“福无双至,祸不单行”,我们继续深入一些隐蔽场景测试,又发现两个必现崩溃的场景:

  • 编辑图片后选择取消
  • 关闭Wi-Fi后发送短视频

分析对比后,发现这两个场景有一个共同的业务逻辑,即是弹出UIAlertView进行消息提示,且崩溃的位置和错误的信息和前面提到的崩溃问题很相似:

Supported orientations has no common orientation with the application, and [_UIAlertShimPresentingViewController shouldAutorotate] is returning YES

也是由于_UIAlertShimPresentingViewController的方向和application的方向不一致导致应用崩溃。

注意,此时,我们就不能跟前面提到的崩溃问题采用同样的方法进行修复了! 因为,_UIAlertShimPresentingViewController是系统内部的类,我们没法重写其shouldAutorotate方法。

所以,我们开始怀疑是否在iOS8.3系统中,是不是所有调用UIAlertView的地方都会发生崩溃?

但在选择了几个调用UIAlertView的界面进行验证后,发现并没有崩溃发生。这种情况让我们很是困惑,在一番探索后,我们把焦点转移到项目中二次封装的SimpleAlertView上,尝试把出现崩溃场景的UIAlertView换成SimpleAlertView,联调测试验证后发现崩溃问题没有再出现。

于是,我们得到一个解决此类崩溃问题的方法:

将工程中所有调用UIAlertView执行UI提示的逻辑全部替换为调用SimpleAlertView执行,当然,还需根据不同的场景修改适配UI样式和交互表现。

但古人有曰,三思而后行。

我们在工程中搜索UIAlertView的调用,发现竟有500+的调用,分别分布在300+的文件中,如果替换的话,其潜在风险和工作量都要仔细考量,而且还需针对不同场景修改UI样式和交互表现,不可取!

所以,我们否决了此解决方法,继续分析问题并探索其他的解决方法。

在前面的验证过程中,我们发现并非所有出现UIAlertView的界面都发生了崩溃,而是只有三个场景出现此类问题,而且都和图片选择器有关,于是把焦点又转移到图片选择器相关的逻辑,并进行了一系列的检查和验证:

  1. Review代码,确认图片选择器里面的shouldAutorotate方法返回值确实为NO
  2. 测试在3G环境下拍摄短视频发送,弹出流量提示框,无崩溃发生
  3. 从图片选择器界面发送短视频,弹出流量提示框时,发生崩溃

由此,我们断定问题在图片选择器的相关处理中。

于是又搜索了其他场景使用UIAlertView但没有崩溃的代码,对比发现二者的supportedInterfaceOrientations方法有一些差异:

  • 图片选择器的视图控制器里面supportedInterfaceOrientations方法返回值为UIInterfaceOrientationPortrait (NSUInteger) supportedInterfaceOrientations { return UIInterfaceOrientationPortrait; }
  • 其他场景的supportedInterfaceOrientations方法返回值为UIInterfaceOrientationMaskPortrait (NSUInteger) supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; }

此处必有蹊跷!

我们火速进行修复尝试:

将图片选择器界面的视图控制器的supportedInterfaceOrientations方法返回值改为UIInterfaceOrientationMaskPortrait

编译联调验证,果然没有发生崩溃。

我们断定在iOS8.3系统出现的UIAlertView发生崩溃的根本原因可能在于此,于是又将QQMarkActionSheetController_FixPos中重写的shouldAutorotate方法删除,测试验证发现没有发生崩溃,继续验证其他曾发生崩溃的场景,崩溃问题没有发生。

终于,我们得出此崩溃问题的根因。

崩溃原因总结

如果在视图控制器中重写supportedInterfaceOrientations方法,并将返回值设为UIInterfaceOrientationPortrait的话,那么在此视图控制器或子视图中弹出UIAlertView时,就会发生崩溃。

查阅了开发文档了解supportedInterfaceOrientations方法的使用,发现其返回值实际是UIInterfaceOrientationMask 类型,而项目中却返回了UIInterfaceOrientation类型,二者虽然长得很相似,但用处完全不一样:

  • UIInterfaceOrientationMask类型用来表示UIViewController能支持的方向
  • UIInterfaceOrientation类型用来表示application当前的方向

如果在iOS8.3系统上两者混用,系统新增的检查判断会发现此问题,并抛出异常,崩溃就这样产生了。

小编有话说

  • 在开发过程中对于系统常量的引用及其含义要加强关注,尤其是遇到此类“兄弟”模样的常量时,避免因理解不清或笔误而造成问题。
  • 在系统版本更新时,要及时关注系统API和常量定义的变化,对功能代码进行兼容性调整。

不总结哪来经验,不分享经验何用?

在此小编号召大家多总结,互分享,踊跃给我们投稿,把自己踩过并爬出来的坑树个指示牌警醒后人,让猿们的开发生活更加美好!

投稿方式:将文章和个人介绍邮件到 bugly@tencent.com,字数不限。

腾讯Bugly,最专业的质量跟踪平台

本文分享自微信公众号 - 腾讯Bugly(weixinBugly)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2015-04-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏李成熙heyli

性能优化三部曲之三——Node直出让你的网页秒开

项目: 手Q群成员分布直出 原因: 为家校群业务直出做准备 群成员分布业务是小型业务,而且逻辑相当简单,方便做直出试验田 基本概念: 直出其实并不算是新概念。只...

84570
来自专栏魏艾斯博客www.vpsss.net

宝塔 Linux 面板 RPM 极速安装体验过程

33930
来自专栏大史住在大前端

大前端的自动化工厂(2)—— SB Family

原文链接:https://bbs.huaweicloud.com/blogs/53c0c3509b7a11e89fc57ca23e93a89f

11330
来自专栏程序员宝库

15 个有趣的 JS 和 CSS 库

作者:Danny Markov,译者:IT程序狮 译文:https://zhuanlan.zhihu.com/p/31321429 原文:https://tut...

61270
来自专栏钱曙光的专栏

一周极客热文:厌倦了编程书?3种提高编程技能的有趣方法来帮忙

Code Combat 如果你曾经从书上学习编写代码,你就知道那有多乏味。为什么不试试一些激动人心的方法来使学习更有乐趣呢?下面介绍的这些网站每个都有自己独特...

22960
来自专栏葡萄城控件技术团队

TypeScript VS JavaScript 深度对比

19140
来自专栏性能与架构

小程序优秀开发资源

下面是一些 github 上比较受欢迎的小程序项目,包括开发框架、UI组件等 labrador (开发框架) 特性: 支持加载海量NPM包 支持ES6/7标准代...

46850
来自专栏IT大咖说

2018年前端流行哪些技术?

32110
来自专栏web前端教室

[web零基础课]~记一个自定义checkBox标签的进化过程&&电商项目作业检查--张潇x

继昨天讲完了jq插件的二种编写方法和区别之后,今天的web前端零基础课中,又回过头来继续把电商网站中的checkBox复选框,进行了进一步的封装与自定义。 //...

23560
来自专栏伪君子的梦呓

推荐几个油猴脚本

油猴,也就是 Tampermonkey 是我每一台电脑都会安装的东西,也是我会给熟人介绍和安装的东西。没什么好说的,就是好用。

7.4K20

扫码关注云+社区

领取腾讯云代金券