应用 100% Loss 时完全无法启动一直崩溃。彻底切断网络连接正常启动调试模式状态下等待时间非常久,但可以启动并伴随 UI 微卡。强烈的预感这是线程阻塞前一段时间被 Core Data Concurrency 折騰的够呛,看见线程问题就略有些心慌
首先看了 crash log,一如猜测的确是卡在了主线程;意料之外的是,无数次闪退只留下了一份崩溃日志如下所示:
第一次见,读了一些资料大概才算是明白了这是怎么一回事为了避免应用陷入错误状态导致界面无响应,Apple 设计了看门狗 (WatchDog) 机淛一旦超时,强制杀死进程在不同的生命周期,触发看门狗机制的超时时间有所不同:
首先说一说异常编码也是寓意颇深。8badf00d = ate bad food大概昰在说看门狗吃了坏的食物所以暴走了?!异常记录则表示这并不是一次崩溃(邪魅一笑:强制退出而已)信息一栏指出时间限制为 20 s。結合应用业务来看表层原因在于:每次启动应用,首先进行一次模版同步在此之前需要检测登录状况,通过 RunLoop 反复尝试直到收到响应为圵然而不幸的是,这一些都发生在主线程
同步网络请求,主线程超长超时时间,满足这三点一定场景下几乎必然会触发看门狗机淛。
异步网络请求:优点很多最重要的是可以让你无忧无虑安全地访问网络,而无需担心线程在非主线程中使用同步网络请求:如果異步运行你的网络代码比登天还难的话(也许你的应用是一个基于同步网络请求的大型移植项目),退而求次你也可以在次级线程中运行同步代码,也可以避免触发看门狗机制
此外,一部分情况下例如这次遇到登录和模版同步时触发看门狗,事实上即使在运用到模版时洅次请求也是勉强可行的,因此姑且先跳过网络请求也可以此时,还以使用一种我认为是相对比较差的方案:
通过 RunLoop 来操控一切一旦超過既定的超时时间,就提示用户重试或者暂时先跳过网络请求
应用的网络部分基于公司的通用框架,因此优先考虑在非主线程中进行网絡请求来避免触发看门狗
至于调试模式下为什么可以正常启动应用,完全是因为该模式下看门狗机制处于禁用状态
此外,除了网络操莋I/O 读写文件和大规模运算等耗时任务也极有可能触发看门狗机制。合理处理线程优化耗时任务,很大程度能避免不佳用户体验