iOS常见崩溃简介

1. 崩溃

多指在移动设备(如iOS、Android设备)中或不可移动设备(如:Windows、Linux等设备),
在打开或使用应用程序时出现的突然退出中断的情况(类似于Windows的应用程序崩溃)。

多表现为:应用程序画面一闪而过,随即退回到桌面。

崩溃会影响用户体验,造成用户流失,因此,我们要重视崩溃
在这里插入图片描述

根据不同场景,崩溃收集方式不同

Xcode编译期间:

在这里插入图片描述

测试机获取:

Xcode->Window->Devices and Simulators
在这里插入图片描述
或者
设置->隐私->分析与改进

线上崩溃采集:

封装好的三方,直接接入的:友盟、bugly、听云
开源的SDK:KSCrash、plcrashreporter

2. 崩溃产生的原因

划分方式一:

  • cpu无法执行的代码
  • 被系统强杀
  • 语言触发异常

2.1 cpu无法执行的代码

  • 无效指令或操作
  • 访问无效地址及不具有权限的内存地址
  • 除以0等
  • 僵尸对象

2.2 被系统强杀

  • 应用内存消耗过高,即OOM问题
  • 主线程长时间无法响应ANR
  • 资源异常
  • 死锁
  • 非法的应用签名
  • 后台执行超时

2.3 语言触发异常

  • OC语言抛出异常
  • C++抛出异常

划分方式二:

除了上面的划分方式,崩溃还可以按:软件异常硬件异常划分

软件异常:
软件异常主要来自 kill(),pthread_kill()。iOS 中的 NSException 未捕获,abort 都属于这种情况。

硬件异常:
硬件的信号始于处理器 trap,是和平台相关的。野指针崩溃大部分是硬件异常。

软件异常的流程是:

软件异常 -> Unix信号

硬件异常的流程是:

硬件异常 -> Mach异常 -> Unix信号
在这里插入图片描述

在这里插入图片描述

Mach 异常:

  • EXC_BAD_ACCESS: 不能访问的内存
  • EXC_BAD_INSTRUCTION: 非法或未定义的指令或操作数
  • EXC_ARITHMETIC: 算术异常(例如除以0)。iOS 默认是不启用的,所以我们一般不会遇到
  • EXC_EMULATION: 执行打算用于支持仿真的指令
  • EXC_SOFTWARE:软件生成的异常,我们在 Crash 日志中一般不会看到这个类型,苹果的日志里会是 EXC_CRASH
  • EXC_BREAKPOINT:跟踪或断点
  • EXC_SYSCALL: UNIX 系统调用
  • EXC_MACH_SYSCALL: Mach 系统调用

UNIX 信号:

  • SIGSEGV,段错误。访问未分配内存、写入没有写权限的内存等。
  • SIGBUS,总线错误。比如内存地址对齐、错误的内存类型访问等。
  • SIGILL,执行了非法指令,一般是可执行文件出现了错误。
  • SIGFPE ,致命的算术运算。比如数值溢出、NaN数值等。
  • SIGABRT,调用 abort() 产生,通过 pthread_kill() 发送。
  • SIGPIPE,管道破裂。通常在进程间通信产生。比如采用FIFO(管道)通信的两个进程,读管道* 没打开或者意外终止就往管道写,写进程会收到SIGPIPE信号。根据苹果相关文档,可以忽略这个信号。
  • SIGSYS,系统调用异常。
  • SIGKILL,此信号表示系统中止进程。崩溃报告会包含代表中止原因的编码。exit(), kill(9) 等函数调用。iOS 系统杀进程,如 watchDog 杀进程。
  • SIGTRAP,断点指令或者其他trap指令产生。

当我们拦截信号处理之后是可以让程序不崩溃而继续运行的,但是不建议这样做,因为程序已经处于异常不可知状态。
看上图里面最终都会转换为 “UNIX信号”, 是不是代表我们只用监听 “UNIX 信号” 就够了呢?为什么还要拦截 Mach 异常呢?

不是所有的 "Mach异常” 类型都映射到了 “UNIX信号”
“UNIX信号” 在崩溃线程回调,如果遇到 Stackoverflow 问题,已经没有条件(栈空间)再执行回调代码了。

捕获到异常信号后,在处理方法 handleSignalException 里通过 backtrace_symbols 方法就能获取到当前的堆栈信息。
堆栈信息可以先保存在本地,下次启动时再上传到崩溃监控服务器就可以了。

Mach是一个XNU的微内核核心

在这里插入图片描述

3. 崩溃日志包含信息

基本信息:崩溃发生的日期、iOS 版本等
进程信息:崩溃进程的相关信息,比如崩溃报告唯一标识符、唯一键值、设备标识
异常信息:异常类型、异常编码、异常的线程;
线程回溯:崩溃时的方法调用栈

崩溃日志调用栈内容:
在这里插入图片描述
这样直接看崩溃信息的调用栈,是看不懂的

我们需要一个.DSYM文件,dSYM 是保存 函数地址映射信息的中转文件,其中包含文件名、方法名、行号等信息

在这里插入图片描述
一个ipa包,对应一个.DSYM文件

在这里插入图片描述
通过.DSYM文件的解析,就可以找到对应的文件名和函数名

4. 开发中常见崩溃

  • unrecognized selector crash
  • KVO crash
  • NSNotification crash
  • NSTimer crash
  • Container crash(数组越界,插nil等)
  • NSString crash (字符串操作的crash)
  • UI not on Main Thread Crash (非主线程刷UI(机制待改善))

unrecognized selector crash

当一个对象找不到对应的方法实现的时候,会报此类错误

在找不到方法时,查找方法将会进入方法forward流程,系统给了三次补救的机会,
所以我们要解决这个问题,在这三次均可以解决这个问题
在这里插入图片描述

KVO crash

KVO监听对象属性值的改变

KVO 日常使用造成崩溃的原因通常有以下几个:

  • KVO 添加次数和移除次数不匹配:
  • 移除了未注册的观察者,导致崩溃。
  • 重复移除多次,移除次数多于添加次数,导致崩溃。
  • 重复添加多次,虽然不会崩溃,但是发生改变时,也同时会被观察多次。
  • 被观察者提前被释放,被观察者在 dealloc 时仍然注册着 KVO,导致崩溃。

NSNotification crash

当一个对象添加了notification之后,如果dealloc的时候,仍然持有notification,就会出现NSNotification类型的crash。

在iOS9以及iOS9以后,可以不做移除通知操作

NSTimer crash

一般是在定时器被target强引用没有被释放,产生内存泄露,或者在定时器触发的时候导致崩溃
解决方案:
1.NSTimer使用Block,对其target不强引用
2.是否找到一个合适的时机,在确定NSTimer已经失效的情况下,让NSTimer自动invalidate
3.使用中间变量

类族(NSArray,NSMutableArray,NSDictonary,NSMutableDictionary)

  • 插入空对象
  • 数组越界
  • 不可变类型插入数据

建议:

  • 加三目运算符,防止数据为空
  • 数组取值的时候,判断数组个数
  • 遇到可变类型,使用strong修饰

非主线程刷UI

UI刷新,必须在主线程操作
在子线程中,需要刷新UI的时候,要切换到主线程

野指针

在这里插入图片描述

定义:当所指向的对象被释放或者收回,但是对该指针没有作任何的修改,以至于该指针仍旧指向已经回收的内存地址,此情况下该指针便称野指针

若操作系统将这部分已经释放的内存重新分配给另外一个进程,而原来的程序重新引用现在的迷途指针,则将产生无法预料的后果。因为此时迷途指针所指向的内存现在包含的已经完全是不同的数据。

在这里插入图片描述

解决方法:

Xcode开启僵尸对象监听
在这里插入图片描述

使用MLeaksFinder或其他三方库,排查内存泄露问题
在这里插入图片描述

使用JJException,减少App闪退
当然,最好做到:开发过程不使用,正式包开启
在这里插入图片描述


参考资料:
iOS 野指针处理
iOS野指针定位总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/545249.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于springboot+vue实现艺术水平考级报名系统【项目源码+论文说明】计算机毕业设计

基于springbootvue实现艺术水平考级报名系统演示 摘要 本次毕业设计基于SpringBoot框架开发了一款艺术水平考级报名管理系统。该系统为考生提供了线上报名、准考证管理等核心功能,并为系统管理员提供了在线发布考试信息、对报名考生进行审核等管理功能。通过该系统…

从政府工作报告中的IT热词统计探计算机行业发展(二)人工智能+:3次

政府工作报告作为政府工作的全面总结和未来规划,不仅反映了国家整体的发展态势,也为各行各业提供了发展的指引和参考。随着信息技术的快速发展,计算机行业已经成为推动经济社会发展的重要引擎之一。因此,从政府工作报告中探寻计算…

基于VJ算法(Viola-Jones algorithm)的人面定位算法,Matlab实现

博主简介: 专注、专一于Matlab图像处理学习、交流,matlab图像代码代做/项目合作可以联系(QQ:3249726188) 个人主页:Matlab_ImagePro-CSDN博客 原则:代码均由本人编写完成,非中介,提供…

Python之Web开发中级教程----搭建Web框架二

Python之Web开发中级教程----搭建Web框架二 搭建虚拟环境 虚拟环境的作用 虚拟环境可以搭建独立的python运行环境, 使得单个项目的运行环境与其它项目互不影响. 搭建虚拟环境 (1)安装 sudo pip install virtualenv sudo pip install virtualenvwra…

JAVA13多行文本java14模式变量

文章目录 多行文本模式变量 多行文本 在JAVA13中,终于是支持多行文本字面量了。而且最关键的是为了源代码更加美观,还自动去掉了每行文本前面的空格。如下面的例子: public class MultilineStringDemo {public static void main(String[] ar…

静态库与动态库的制作和使用

个人主页:Lei宝啊 愿所有美好如期而遇 目录 前言 库? 为什么要使用库 静态库 静态库的制作和使用 动态库 动态库的制作和使用 四种方法: 直接将库拷贝(安装)到系统路径中 配置环境变量 软链接 添加配置文件 动态库和静态库同时…

【Hadoop大数据技术】——MapReduce经典案例实战(倒排索引、数据去重、TopN)

📖 前言:MapReduce是一种分布式并行编程模型,是Hadoop核心子项目之一。实验前需确保搭建好Hadoop 3.3.5环境、安装好Eclipse IDE 🔎 【Hadoop大数据技术】——Hadoop概述与搭建环境(学习笔记) 目录 &#…

蓝桥杯2023年省A(一波三折的)【买瓜】折半搜索+剪枝+排序

题目:洛谷 P9234 [蓝桥杯 2023 省 A] 买瓜 折半搜索 一开始觉得像dp,试着写了,显然过不了,但我实在觉得搜索也过不了啊,去看题解,发现使用了折半搜索(每天都觉得啥都不会捏 折半搜索就是先搜一…

HarmonyOS NEXT应用开发—发布图片评论

介绍 本示例将通过发布图片评论场景,介绍如何使用startAbilityForResult接口拉起相机拍照,并获取相机返回的数据。 效果图预览 使用说明 通过startAbilityForResult接口拉起相机,拍照后获取图片地址。 实现思路 创建CommentData类&#…

Rocky Linux 基本工具的安装

1.系统安装后先查看ip地址 ip addr 2.安装net工具 :ifconfig yum install net-tools 3.安装gcc ;选择都选 y yum install gcc yum install gcc-c 4.安装tcl yum install -y tcl 5.安装lsof (端口查看工具) yum install l…

GIF图片压缩的几种方法

影响GIF大小的因素 尺寸大小帧速率颜色动效复杂程度时长 一般输出gif大小是最后一步,所以前期的尺寸,颜色,动效,时长,这些我们都不能动,但是客户往往要求在100kb且不糊的gif,这时候就比较头疼。 方法1&a…

十五、自回归(AutoRegressive)和自编码(AutoEncoding)语言模型

参考自回归语言模型(AR)和自编码语言模型(AE) 1 自回归语言模型( AR) 自回归语言模型(AR)就是根据上文内容(或下文内容)预测下一个(或前一个&…