UI事务重叠引发的crash

时间:2022-12-22 11:43:10

在ios开发的世界里,通过动画来切换界面使我们早就习以为常的事情,但动画将一个原本同步执行的事务,变成一个异步事务,并由此引发了一系列的陷阱。
最近对公司产品的crashlytics报告进行了一些分析,发现这类bug在各个产品里都占据较高比例,因此总结了一下常见的case。

  1. present ViewController引发的混乱
    present一个controller的时候,如果一个present的动画正在执行过程当中,程序会抛出异常,异常告诉你Attempting to begin a modal transition from * to * while a transition is already in progress. Wait for viewDidAppear/viewDidDisappear to know the current transition has completed
    解决的办法是引入一个present事务控制器,用来对present请求进行排队,这种方案是否足够可靠,还有待验证。

  2. NavigationController引发的混乱
    与present类似,NavigationController的push&pop也会引发类似的错误,症状是,在多重push的时候不会立即crash,视图的内容部分会一团漆黑,但是在回退的时候会crash,异常是Fatal Exception: NSInvalidArgumentException Can't add self as subview,从crash的调用栈看,是navigationbar内部错误。
    解决的方法是可以继承UINavigationController,通过UINavigationControllerDelegate来监测状态,如果当前正在处于上一个push的执行过程当中,可以忽略掉新的push请求。

  3. UIScrollView(UITableView)的delegate引发的崩溃
    虽然ios5.0开始就已经支持weak引用,但很多的cocoa Touch类的delegate属性还是assign,这说明他们保存了一个不安全的引用。UIScrollView就是这样,如果controller里面有个UIScrollView,delegate属性是自身,那么有可能发生这样的情况:uiscrollview正在进行一个动画事务(出问题的case中,动画往往不是由于用户操作导致的),用户退出了当前的controller,动画完成的时候controller可能已经被dealloc,此时会发生EXEC_BAD_ACCESS崩溃。
    如果crash的的栈显示与UIScrollView有关,又表明是在Animation结束的时候,那么就很有可能是这个原因;这样的bug往往很难复现,据经验,一般出现在那些通过定时器启动动画的场合。
    因此,作为一种防御性的手段,建议在controller的dealloc里面,将相关的delegate置为nil

  4. 多个UI事件同时发生引发的混乱
    一个同事提供的线索,如果你同时点击UI页面的多个可点击控件,UI有可能发生混乱。
    比如同时点击多个button,uicontrol,绑定gesture的uiview等,只要刻意试一下我们的产品都有这个问题。
    现在的解决的方案是将相关可点击view的exclusiveTouch属性设置为true,如果工程里面UI控件都是用工厂方法创建的,那么改起来还是很方便的。
    不过gesture是不受这个属性的影响的,目前还没有发现如何解决,因此只能规避,如果能够使用UIControl来解决的问题,就不要使用UIView+Gesture来解决。
    这种问题如果不是刻意的去操作,一般还是很少会暴露的。

上面的几点是最近对线上一类疑难bug分析之后总结出来的根本原因;其本质上都是UI事务叠加导致的。上面1和2发生的根源一般都是,定时器或后台逻辑促发的界面切换,恰好和另一个界面切换撞在了一起,因此在测试的时候可能很难发现;在用户手上复现的概率也不是特别高,但总是会出现。所以在设计应用的时候,最好要避免这种从非用户操作导致的界面切换。

如果每个UI事务都不加动画、同步完成,那么就不会有这些情况,但这是不可能的。驱动App运行的所有事件源,包括定时任务、异步任务、用户操作、外部事件(比如推送消息)等,叠加在一起,使得完全避免上述的情况几乎不可能,关键是ios的UI框架对此基本不设防,只能靠我们自己积累经验,谨慎小心。

UI事务重叠引发的crash的更多相关文章

  1. [转]Spring事务嵌套引发的血案---Transaction rolled back because it has been marked as rollback-only

    原文地址:https://blog.csdn.net/f641385712/article/details/80445912 1.概述 想必大家一想到事务,就想到ACID,或者也会想到CAP.但笔者今 ...

  2. Spring事务嵌套引发的问题--Transaction rolled back because it has been marked as rollback-only

    转载https://blog.csdn.net/f641385712/article/details/80445912 读了两边才找到问题

  3. 用Fragment制作的Tab页面产生的UI重叠问题

    本文出处:http://blog.csdn.net/twilight041132/article/details/43812745 在用Fragment做Tab页面,发现有时候进入应用会同时显示多个T ...

  4. iOS:项目中疑难Crash问题集锦

    项目中疑难Crash问题集锦 iOS App运行中遇到Crash的情况相信大家都遇到过,开发和者测试中遇到了可能很方便的办法就是直接拿着设备连接一下,然后使用Xcode自带的工具就可以解析出Crash ...

  5. JNI NDK开发Crash错误定位 调试

    总结: 搜索backtrace  然后: $ /d/android-ndk-r10c/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86 ...

  6. Android NDK开发Crash错误定位[转]

    使用 ndk-stack 的时候需要你的 lib 编译为 debug版的,通常需要下面的修改: 1. 修改 android.mk,增加,为 LOCAL_CFLAGS 增加 -g 选项 2. 修改 ap ...

  7. 一些Windows API导致的Crash以及使用问题总结

    RegQueryValueEx gethostbyname/getaddrinfo _localtime64 FindFirstFile/FindNextFile VerQueryValue Crea ...

  8. Sqlserver事务隔离级别详解

    sqlserver存储方式   页    sqlserver是以页的形式存储数据,每个数据页的大小为8KB,sqlserver会把空间分为多个页,sqlserver与数据交互单位最小的io操作就是页级 ...

  9. sqlserver Distributed Transaction 分布式事务

    在webapi+ef+sqlserver开发项目时,利用transcope实现应用层级的事务时,偶尔会报分布式事务错误,而且很而复现,特别蛋疼.现将自己的解决方法初步整理下. 分析原因:搭建repos ...

随机推荐

  1. js中Prototype属性解释及常用方法

    1.prototype的定义 javascript中的每个对象都有prototype属性,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用. 每一个构造函数都有一个属 ...

  2. Cow Bowling

    Cow Bowling Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 15585 Accepted: 10363 Descrip ...

  3. 有用的dede表单代码

    <form action="" class="demoform">                <table>             ...

  4. Codeforces Round &num;180 &lpar;Div&period; 2&rpar; B&period; Sail 贪心

    B. Sail 题目连接: http://www.codeforces.com/contest/298/problem/B Description The polar bears are going ...

  5. Matlab plotyy函数的使用及问题总结

    MATLAB函数,用来绘制双纵坐标图. 调用格式: 1.plotyy(X1,Y1,X2,Y2):以左.右不同纵轴绘制X1-Y1.X2-Y2两条曲线. 2.plotyy(X1,Y1,X2,Y2,FUN1 ...

  6. &period;net 开发框架

    .NET开发人员值得关注的七个开源项目 2010年07月02日09:33 it168网站原创 作者:黄永兵 编译 编辑:胡铭娅 我要评论(0) [IT168技术分析]微软近几年在.NET社区开源项目方 ...

  7. java第十次笔记

  8. 如何编写一个SQL注入工具

    0x01  前言 一直在思考如何编写一个自动化注入工具,这款工具不用太复杂,但是可以用最简单.最直接的方式来获取数据库信息,根据自定义构造的payload来绕过防护,这样子就可以. 0x02 SQL注 ...

  9. 优化 resolv&period;conf

    DNS lookup 在把域名解析成 IP 过程中耽误了不少时间,尤其是访问比较复杂的网站的时候,比如某个页面包含多个 url,一次请求需要做多次 DNS 解析,并且从用户浏览器到 DNS serve ...

  10. js 日历插件开发

    1.HTML完整代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...