再谈 iOS App Crash 防护

本文深入探讨了iOS应用中的Crash防护,分析了Crash防护的多种方案,包括NSSetUncaughtExceptionHandler、BSD信号处理和Objective-C的try-catch。重点介绍了Baymax方案,一种通过预防异常来避免Crash的策略。实践中遇到的高频调用性能问题、UnrecognizedSelector防护坑、SDK更新稳定性等挑战以及防护的代价也进行了详细讨论。
摘要由CSDN通过智能技术生成

在移动开发中,App 的闪退率是工程师十分关注且又头疼的事情。去年,网易杭州研究院曾经针对 crash 的防护有提出『大白健康系统–iOS APP 运行时 Crash 自动修复系统』方案,使得 crash 防护这个想法真正被落实,但至今该方案的具体实现并没有被开源。经过一年的时间,圈子里也有一些开发朋友,基于这套方案设计并开源了自己的 “Baymax”,比如『老司机 iOS 周报第七期』中曾提到的 BayMaxProtector。本文将会针对网易 Baymax 这套方案,结合团队内的实践结果,总结其在生产环境中可能遇到的问题及其解决方案,并提出一些自己对这套方案的思考。友情提示,阅读本文前需对网易『大白健康系统–iOS APP 运行时 Crash 自动修复系统』一文有所了解,该文中已有的实现方案,本文不会再花更多笔墨进行赘述。

Crash 防护可选的方案

Crash 是什么?

在探讨 Crash 防护的方案之前,我们有必要对计算机领域 Crash 这个概念进行重新认识。对于 Crash 的概念,维基百科中是这么定义的:

In computing, a crash (or system crash) occurs when a computer program, such as a software application or an operating system, stops functioning properly and exits.

An application typically crashes when it performs an operation that is not allowed by the operating system. The operating system then triggers an exception or signal in the application. Unix applications traditionally responded to the signal by dumping core. Most Windows and Unix GUI applications respond by displaying a dialogue box (such as the one shown to the right) with the option to attach a debugger if one is installed. Some applications attempt to recover from the error and continue running instead of exiting.

对于我们 iOS 应用层的 App,可简单总结为应用执行了某些不被允许的操作触发了系统抛出异常信号但又没有处理这些异常信号从而被杀掉的现象,比如常见的闪退(crash to desktop)。在我们开发领域从抛出异常的对象上来看,一共可以分为三类内核导致的异常应用自身的异常其他进程导致的异常

  • 由操作系统内核捕获硬件产生的异常信号,比如 EXC_BAD_ACCESS,这类异常如果没有被处理掉的话,会被转发到 SIGBUS 或 SIGSEGV 等类型的 BSD 信号;
  • 由 SDK 开发者或上层应用开发者主动抛出的异常信号,比如各种常见的 NSException,这类异常苹果为了统一处理,最终会被转发为 SIGABRT 类的 BSD 信号;
  • 其他进程杀死你的应用;

这里我们主要谈最常见的前两种异常。

可选的 Crash 防护方案

上面已经提到了 Crash 实际上我们触发了异常,但又没有去处理这些异常而导致的结果。那么很自然的第一个防护方案便可以想到是去处理这些异常

通过 NSUncaughtExceptionHandler 来捕获并处理异常

苹果的确提供有异常捕获的 API 以供开发者使用——NSSetUncaughtExceptionHandler,开发者只需要传入处理函数的指针,便可以处理掉应用中抛出的 NSException 类的异常。代码写起来就是:

NSSetUncaughtExceptionHandler(&HandleException);

通过 BSD 的 signal 来捕获并处理异常

由于苹果将所有异常最终都转换成了 BSD 信号的发出,那么我们就可以去捕获这个信号来处理这些异常,从而达到 Crash 防护的目的。系统也有提供相关 API 实现:

void    (*signal(int, void (*)(int)))(int
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值