iOS程序异常crash捕获与拦截
对于iOS应用try-catch并不能捕获所有异常,也就是说有时候我们加上了try-catch可是程序还是会Crash,目前我所总结有两种:一种是由EXC_BAD_ACCESS引起的,原因是访问了不属于本进程的内存地址,有可能是访问已被释放的内存;另一种是未被捕获的Objective-C异常(NSException),导致程序向自身发送了SIGABRT信号而崩溃。其实对于未捕获的Objective-C异常,我们是有办法将它记录下来的,如果日志记录得当,能够解决绝大部分崩溃的问题。下面对于UI线程与后台线程分别说明。
传统的捕获异常的方式中所熟知try-catch-finally,但有些时候一些iOS系统的api是原生的C语法格式例如:sqlite3.c,UnGzip.c这些是不支持OC或者C++的try-catch机制即使有异常也是捕获不到,或者是一些内存的问题等在try里面还是会无情的Crash。
iOSSDK中提供了一个现成的函数NSSetUncaughtExceptionHandler用来做异常处理,但功能非常有限,而引起崩溃的大多数原因如:内存访问错误,重复释放等错误就无能为力了,因为这种错误它抛出的是Signal,所以必须要专门做Signal处理。代码如下
通过上图的操作我们就完成了iOS SDK给我们提供的捕捉异常处理,我们只需要在HandleException方法中纪录我们的异常信息即可。但这仅仅是捕获一般的OC异常信息,对于Signal异常信号我们仍然无法捕获到,此时我们就需要去注册一些Signal信号来帮助我们捕获Signal异常。首先介绍一下Signal信号:
signal。既信号量,ios是Linux内核,在程序发生未捕获异常时,程序会向自身发送信号(SIGABRT、SIGBUS、SIGHUP等。。。),然后程序直接闪退。。。有时候这是无可避免的。作为一款优秀的软件,必须要有异常报告模块,让用户给你发送异常报告信息。这样才能根据异常信息来做相应地Debug工作。在iOS SDK
signal.h里面有31种信号方式这里不做一一解释。
下面说一下怎么注册这些信号量来帮助我们记录到异常信息。代码如下:
上图中的signal(SIGHUP, void(*)(int));方法为iOS signal.h中的注册信号量的方法其中第二个参数为收到信号的回调函数,我们通过这个回调函数可以根据我们的需求做一些处理。
小结:try-Catch只能帮助我们拦截一些bug或者帮助我们提供一些错误信息,要从根本上解决程序的问题还需要不断的调试,优化。
作者:Olivia_Zqy