对比解析之EXC_BAD_ACCESS & 空指针 & 野指针 & 僵尸对象

空指针

* 没有存储任何内存地址的指针就称为空指针(NULL指针);

* 空指针就是被赋值为0的指针,在没有被具体初始化之前,其值为0。

例:

Monkey *m1 = NULL;

Monkey *m2 = nil;

野指针

野指针,也称为悬挂指针,是指向"垃圾"内存(不可用内存)的指针,即指向的对象已经被释放了,指针指向随机的未知内存。

两者对比

* 野指针和空指针是不一样的;

* 利用空指针发消息是没有任何问题的,野指针是非常危险的。使用野指针访问僵尸对象,有的时候会出问题,有的时候不会出问题。当野指针指向的僵尸对象所占用的空间还没有分配给别人的时候,其实是可以访问的。因为对象的数据还在。当野指针指向的对象所占用的空间分配给了别人的时候,访问就会出问题。所以,不要通过一个野指针去访问一个僵尸对象。访问的含义包括多种情况,例如:向野指针发送消息,读写野指针本来指向的对象的成员变量等等。

僵尸对象

僵尸对象指的是引用计数为0被系统回收的对象,但这些对象暂时还存在于内存中,对象被释放后所占用的内存在没有被复写(重新分配给其他对象),且理论上还是可以使用的,但是不稳定。

EXC_BAD_ACCESS

什么是EXC_BAD_ACCESS

异常(EXC)+ 不能访问该存储器区域(BAD ACCESS)。

简单的解释

无论何时你遇到了EXC_BAD_ACCESS,那就意味着你正在发送一个消息给一个对象,而这个对象已经被释放掉了。

专业的解释

BAD_ACCESS 报错属于内存访问错误,错误的原因是访问了野指针(悬挂指针)。

如何调试BAD_ACCESS错误

1. 僵尸调试模式

让EXC_BAD_ACCESS难以调试的原因是,你不知道你的应用程序试图访问哪个对象。在Xcode中,为了调试,启用僵尸对象,即被释放的对象将会以僵尸的形式被保留。如果向僵尸对象发送消息,应用程序将会由于EXC_BAD_ACCESS而崩溃。Xcode可以告诉你试图访问哪个对象,这使得查找问题原因容易得多。

如何开启僵尸调试模式


对比解析之EXC_BAD_ACCESS & 空指针 & 野指针 & 僵尸对象_第1张图片
step1


对比解析之EXC_BAD_ACCESS & 空指针 & 野指针 & 僵尸对象_第2张图片
step2

为什么不默认开启僵尸对象

因为一旦开启,每次通过指针访问对象的时候都会去检查指针指向的对象是否为僵尸对象,这样会比较影响效率。

2. Analyze分析

Xcode的Analyze静态分析帮助检查可能会出问题的地方。

如何进行Analyze分析


对比解析之EXC_BAD_ACCESS & 空指针 & 野指针 & 僵尸对象_第3张图片

Xcode的 Product菜单选择 Analyze,当它完成的时候你会在左边的 Issue Navigator看到问题列表。由Analyze发现的问题用蓝色高亮显示。当你点击一个问题,Xcode的会指向问题代码块,这些正是你要的注意的地方,不过Xcode仅仅是建议。

如何避免僵尸对象报错

当一个指针变为野指针以后,就把这个指针的值设置为nil。

你可能感兴趣的:(对比解析之EXC_BAD_ACCESS & 空指针 & 野指针 & 僵尸对象)