简介
在开发 iOS 应用, 解决 Crash 问题始终是一个难题. Crash 分为两种, 一种是由 EXC_BAD_ACCESS 引起的, 原因是访问了不属于本进程的内存地址, 有可能是访问已被释放的内存; 另一种是未被捕获的 Objective-C 异常, 导致程序向自身发送了 UNIX 信号而崩溃. 对于这两种 Crash 的捕获, 精准高效的收集线上崩溃可以帮助我们更好的解决问题和提高用户体验, 现在比较成熟的崩溃收集工具也比较多, 比如: 友盟统计, Crashlytics, 腾讯的 bugly 等等. 也可以通过自定义 crash 上报, 来处理异常.
问题
但是当自定义 crash 上报收集工具与第三方 crash 收集工具共存的时候, 发现自定义 crash 上报收集工具, 不能捕获到 exception.
原因
- /* Set the uncaught exception handler */
- NSSetUncaughtExceptionHandler(&uncaught_exception_handler);
不管是第三方还是自定义的上报收集工具, 一般会常用注册 ExceptionHandler 的方式, 来捕获 exception, 但是并没有将异常进行抛出, 所以, 当工程中使用了第三方上报收集工具进行异常统计的时候, 我们自己写的异常捕获有可能会失效.
解决方法
首先保存第三方的 ExceptionHandler, 然后在设置自己处理 exception 的 ExceptionHandler, 在自己的 ExceptionHandler 处理完异常之后, 再将异常塞给之前的第三方 ExceptionHandler.
- static NSUncaughtExceptionHandler *_previousHandler;
- // 保存第三方处理异常的 handler
- _previousHandler = NSGetUncaughtExceptionHandler();
- // 设置自己处理异常的 handler
- NSSetUncaughtExceptionHandler(&UncaughtExceptionHandlerYourself);
处理自己的异常
- void UncaughtExceptionHandlerYourself(NSException * exception) {}
处理完自己的逻辑之后就需要把 exception 赋值给我们之前保存的 handler, 否则第三方就无法统计到崩溃的数据.
_previousHandler(exception);
总结, 通过这种方法, 第三方和我们上报收集工具, 都可以正常的收集崩溃数据. 第三方上报收集工具捕获到异常, 再处理完自己的逻辑后, 将 exception 抛了出来, 我们自己的崩溃日志收集库收到第三方上报收集工具抛出来的 exception, 处理完自己的逻辑后再将 exception 抛给第三方上报收集工具的 handler.
来源: http://www.jianshu.com/p/a1d02e2a9048