zoukankan      html  css  js  c++  java
  • iOS-野指针与僵尸对象

    • 野指针.

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

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

          • 当野指针指向的僵尸对象所占用的空间还没有分配给别人的时候,这个时候其实是可以访问的.因为对象的数据还在.
          • 当野指针指向的对象所占用的空间分配给了别人的时候 这个时候访问就会出问题. 所以,你不要通过1个野指针去访问1个僵尸对象.

            • 虽然可以通过野指针去访问已经被释放的对象,但是我们不允许这么做.
        • . 僵尸对象检测.

          • 默认情况下. Xcode不会去检测指针指向的对象是否为1个僵尸对象. 能访问就访问 不能访问就报错.
          • 可以开启Xcode的僵尸对象检测. 
            • 那么就会在通过指针访问对象的时候,检测这个对象是否为1个僵尸对象 如果是僵尸对象 就会报错.
        • . 为什么不默认开启僵尸对象检测呢?

          • 因为一旦开启,每次通过指针访问对象的时候.都会去检查指针指向的对象是否为僵尸对象.
          • 那么这样的话 就影响效率了.
    • . 如何避免僵尸对象报错. 
        • 当1个指针变为野指针以后. 就把这个指针的值设置为nil
    • 僵尸对象无法复活.
        • 当1个对象的引用计数器变为0以后 这个对象就被释放了.
        • 就无法取操作这个僵尸对象了. 所有对这个对象的操作都是无效的.

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


    • 空指针 

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


     

    开启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

     
     

    用心去理解

  • 相关阅读:
    EXT--columnWidth
    EXT经验--查询items的xtype
    修改VS解决方案及工程名,解决如何打开高/版本VS项目
    jQuery Ajax 全解析(转)
    MS SqlSever一千万条以上记录分页数据库优化经验总结【索引优化 + 代码优化】[转]
    .net框架版本说明
    [Ajax] 使用Ajax异步上传图片文件(非Form表单提交)
    CodeSmith 7.01破解下载
    jQuery插件之Cookie
    Oracle笔记 目录索引
  • 原文地址:https://www.cnblogs.com/junhuawang/p/9213093.html
Copyright © 2011-2022 走看看