iOS-野指针与僵尸对象

 

  • 野指针.编辑器

  • C语言: 当咱们声明1个指针变量,没有为这个指针变量赋初始值.这个指针变量的值是1个垃圾指 指向1块随机的内存空间。
  • OC语言: 指针指向的对象已经被回收掉了.这个指针就叫作野指针.

 

  • 僵尸对象 
      一个OC对象引用计数为0被释放后就变成僵尸对象了,僵尸对象的内存已经被系统回收,虽然可能该对象还存在,数据依然在内存中,但僵尸对象已是不稳定对象了,不能够再访问或者使用,它的内存是随时可能被别的对象申请而占用的
  • . 内存回收的本质.
  • 申请1块空间,其实是向系统申请1块别人再也不使用的空间.
  • 释放1块空间,指的是占用的空间再也不使用,这个时候系统能够分配给别人去使用.
  • 在这个个空间分配给别人以前 数据仍是存在的.
  • OC对象释放之后,表示OC对象占用的空间能够分配给别人.
  • 可是再分配给别人以前 这个空间仍然存在 对象的数据仍然存在.
  • 僵尸对象: 1个已经被释放的对象 就叫作僵尸对象.
      • . 使用野指针访问僵尸对象.有的时候会出问题报错(EXC_BAD_ACCESS),有的时候不会出问题.post

        • 当野指针指向的僵尸对象所占用的空间尚未分配给别人的时候,这个时候实际上是能够访问的.由于对象的数据还在.
        • 当野指针指向的对象所占用的空间分配给了别人的时候 这个时候访问就会出问题. 因此,你不要经过1个野指针去访问1个僵尸对象.spa

          • 虽然能够经过野指针去访问已经被释放的对象,可是咱们不容许这么作.
      • . 僵尸对象检测.指针

        • 默认状况下. Xcode不会去检测指针指向的对象是否为1个僵尸对象. 能访问就访问 不能访问就报错.
        • 能够开启Xcode的僵尸对象检测. 
          • 那么就会在经过指针访问对象的时候,检测这个对象是否为1个僵尸对象 若是是僵尸对象 就会报错.
      • . 为何不默认开启僵尸对象检测呢?调试

        • 由于一旦开启,每次经过指针访问对象的时候.都会去检查指针指向的对象是否为僵尸对象.
        • 那么这样的话 就影响效率了.

 

  • . 如何避免僵尸对象报错. 
      • 当1个指针变为野指针之后. 就把这个指针的值设置为nil

 

  • 僵尸对象没法复活.
      • 当1个对象的引用计数器变为0之后 这个对象就被释放了.
      • 就没法取操做这个僵尸对象了. 全部对这个对象的操做都是无效的.code

      • 由于一旦对象被回收 对象就是1个僵尸对象 而访问1个僵尸对象 是没有意义.    对象

 


 

  • 空指针 

    空指针是指没有指向任何东西的指针(存储的东西是nil、NULL、0),给空指针发送消息不会报错blog

 


 

 

开启Xcode对僵尸对象检测调试

BAD_ACCESS 在什么状况下出现

BAD_ACCESS 报错属于内存访问错误,会致使程序崩溃,错误的缘由是访问了野指针(悬挂指针)。野指针指的是原本指针指向的对象已经释放了,但指向该对象的指针没有置 nil,指针指向随机的未知的内存,程序还觉得该指针指向那个对象,致使存在一些潜在的危险访问操做,这些危险访问操做没法被指针指向的未知内存所处理,就会致使BAD_ACCESS错误形成程序崩溃。访问的含义包括多种状况,例如:向野指针发送消息,读写野指针原本指向的对象的成员变量等等。图片

如何调试BAD_ACCESS错误

首先调试BAD_ACCESS错误是比较困难的,咱们知道BAD_ACCESS错误是因为访问了野指针,但程序不会在野指针出现时或者在咱们访问野指针的代码处报错,致使对其难以察觉,调试方法思路以下:内存

 

  • 开启僵尸对象诊断

首先是开启僵尸对象诊断模式,利用僵尸对象来对野指针的出现位置提供线索。咱们知道僵尸对象指的是引用计数为0被系统回收的对象,但这些对象暂时还存在于内存中,且理论上仍是可使用的,可是不稳定。开启僵尸对象诊断后,僵尸对象会暂时保持活跃用于调试,咱们的野指针在对象回收后依然指向该僵尸对象,在访问野指针也就是访问僵尸对象的状况下能够被编辑器检测出来。这个时候仍是会报BAD_ACCESS错误,可是后台会打印出该线索,例以下面的访问野指针打印的后台信息:

 

能够看出Xcode告诉咱们消息发送给了一个僵尸对象,僵尸对象本来是一个实例,但如今该对象被回收了而开发者还试图访问它,由此能够很容易定位问题所在。

另外开启僵尸对象诊断的方法为:打开Xcode顶部导航栏的Product-Scheme-Edit Scheme,在弹出的界面中选中左侧的Run模式,而后勾选右侧Dianostics下的Zombie Objects。

 

为何不默认开启僵尸对象检测呢?

由于一旦开启,每次经过指针访问对象的时候,都会去检查指针指向的对象是否为僵尸对象。因此会影响程序的执行效率,建议关闭。

 

  • Analyze分析

僵尸对象诊断能够帮助快速定位多数状况下的野指针问题,但也有时候不能奏效,这个时候只能利用Xcode的Analyze静态分析帮助检查可能出问题的地方,仔细检查问题所在,比较费时。

使用方法很简单,选中Xcode顶部导航栏Product-Analyze或使用快捷键Command+Shift+B,分析须要花一些时间,而后左侧会列出编辑器发现的存在潜在问题的地方,选中蓝色图标对应的问题项会跳到问题项所在的代码行。但这只能给出一些潜在提示,帮助搜索问题所在,不必定和咱们的bug相关。

这里写图片描述

 

           定位到问题后把野指针至nil

 
 

用心去理解

相关文章
相关标签/搜索