异常与崩溃
一、异常捕获
通过三方捕获的方式,可以选择 Buly 友盟 等。详细的不展开,下面我们只讲底层自己进行异常捕获。
1、iOS异常捕获
开发iOS应用,解决Crash问题始终是一个难题。Crash分为两种,
一种是由EXC_BAD_ACCESS引起的,原因是访问了不属于本进程的内存地址,有可能是访问已被释放的内存;
另一种是未被捕获的Objective-C异常(NSException),导致程序向自身发送了SIGABRT信号而崩溃。其实对于未捕获的Objective-C异常,我们是有办法将它记录下来的,如果日志记录得当,能够解决绝大部分崩溃的问题。
UncaughtExceptionHandler
2、Flutter异常捕获
系统已在performRebuild中异常捕获 FlutterError.onError = (FlutterErrorDetails details) { };
runZoned 中 handleUncaughtError 拦截未处理的异步错误
文档:《Flutter实战第二版:Flutter异常捕获:最终的错误上报代码》
如果我想在应用程序退出时执行一些清理工作,我应该在 RunLoop 的哪个阶段进行操作?
1 | // 程序被手动杀死。即将终止,可以在这里执行一些必要的清理工作 |
applicationWillTerminate:这个方法并不总是可靠的,因为它的调用取决于多种因素,包括用户如何退出应用(例如,通过按 Home 键或通过系统设置)和系统状态。相比之下,RunLoop Observer 提供了一种更为可靠的方法来监听应用生命周期的特定阶段。通过在 RunLoop 的退出阶段添加一个 Observer,你可以确保在 RunLoop 即将退出时执行一些操作,这通常意味着应用即将进入后台或者终止。(还未亲自验证!!!)
1 | // 在 AppDelegate.m 文件中 |
二、如何追踪app
三、起死回生/回光返照
1、iOS 使用Runloop实现起死回生/回光返照
核心:创建一个Runloop,将主线程的所有Runmode都拿过来跑,作为应用程序主Runloop的替代。
但是:这样固然可以实现我们想要做的事情,但是会带来一个问题:因为我们为了继续执行程序而没有将控制权返回给导致崩溃的调用函数,并且我们启动了自己的Runloop,所以永远不会返回到原始的Runloop中去了,这将意味着导致异常的线程使用的堆栈内存将永久泄漏。因此这种类型的方法应被视为调试工具或最后手段,所以,不要在Debug以外的环境使用它。本段摘自:线程保活提醒
视频:“Runloop起死回生/回光返照” 见 00:57:55–01:03:00 的视频 2021-08-21_Crash分析.wmv
文档:RunLoop总结:RunLoop的应用场景(五)阻止App崩溃一次