• 野指针.

  • 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

 
 

用心去理解

iOS-野指针与僵尸对象的更多相关文章

  1. OC中的野指针(僵尸指针)

    涉及到内存管理问题的都是类类型的变量,而在OC中我们操纵这些对象都是通过操纵指向他们的指针来完成的,一致很多时候会忽略指针存在.比如定义UIView * view = [[UIView alloc]i ...

  2. ios野指针的3种常见情况

  3. Objective-C 【单个对象内存管理(野指针&内存泄露)】

    ------------------------------------------- 单个对象内存管理 (1)野指针 ①定义了一个指针变量,但是并没有赋初值,它随机指向一个东西 ②某指针变量指向的内 ...

  4. OC-引用计数器,内存管理,野指针

    总结 全局断点 →-->+-->Add Exception Breakpoint 开启僵尸监听 打开Edit scheme -->Diagnostics-->Enable Zo ...

  5. 七.OC基础加强--1.内存管理 2.野指针,内存泄露 3.set方法的内存管理 4.@property参数 5.@class和循环retain的使用 6.NSString的内存管理

    1,内存管理简单介绍 1,为什么要有内存管理? malloc selloc dealloc```需要回头复习 一般的内存 4s 是512m内存:6 是1024m内存: 当内存过大时,会耗尽内存.出现程 ...

  6. iOS 关于僵尸对象和僵尸指针的那些事儿

    引言 提到僵尸就感到一种恐怖,大家都知道“僵尸”是没有生命的,但是它确实是一种存在的类似生命体的一种生物.哈哈,当然本文的重点不是讨论“僵尸”,而是有关于ios当中经常遇到的僵尸指针(Zombie P ...

  7. iOS中僵尸对象的实现方法

    什么是僵尸对象?所谓僵尸,就是过度释放的对象.在ios开发中,僵尸对象对于开发人员调试程序来说很有用.我们通常将NSZombieEnabled环境变量设置为YES来打开僵尸对象,但这会导致所有的对象都 ...

  8. iOS 类方法 、野指针与空指针

    一.类方法: 不依赖于对象,执行效率更高; 能用类方法解决的问题,尽量使用类方法; 类方法中不能直接访问实例变量(成员变量) 二.野指针和空指针是什么?什么时候产生?怎么避免? 只要一个对象被释放了, ...

  9. iOS开发_内存泄漏、内存溢出和野指针之间的区别

    今天,在工作群中,被问到了内存泄漏和野指针指向的区别,自己答的不是很好,特意回来查了资料,在博文中总结一下经验,欢迎指正. 内存泄漏:是指在堆区,alloc 或new 创建了一个对象,但是并没有放到自 ...

随机推荐

  1. C# 计算地图上某个坐标点的是否在多边形内

    这个方法引用自群友的博客 https://www.xiaofengyu.com/?p=143 使用百度地图的时候,常常会用到判断一个点是否在一个多边形的范围内,该方法用到的是射线法, 通过修改Java ...

  2. JS_高程4.变量,作用域和内存问题(2)执行环境及作用域

    1.执行环境:执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为, 每个执行环境都有一个与之相关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中. 2.全局执行环境: 最外围的 ...

  3. pygame-KidsCanCode系列jumpy-part15-PowerUp加速器

    这一节我们给游戏增加点额外的奖励,大多数游戏中都会有金币.装备啥的来激励玩家,在jumpy这个游戏中,我们也可以增加类似的道具:加速器.效果图如下: 档板上会随机出现一些加速器(power up),小 ...

  4. 附近有什么?8款可以查周边的App

    如今科技发达的时代,手机的功能不仅仅只是能通讯聊天,而是逐渐的走进了人们的生活中.因为有了APP,我们的生活才更丰富,并且有很多是我们生活中不可缺少的软件,而这些软件便是根据手机中的GPS定位系统而来 ...

  5. Collection was modified; enumeration operation may not execute Dictionary 集合已修改;可能无法执行枚举操作

    public void ForeachDic() { Dictionary dic = new Dictionary(); dic.Add("1", 10); dic.Add(&q ...

  6. iOS:类似于网易云音乐的刷新条目显示弹框

    一.介绍 在app中使用刷新控件或者第三方刷新库是最常见的功能,在请求服务器时,获取数据的过程是处于不可见状态的,那么通过这个刷新状态可以给用户以直观的感受,这是增强用户体验的一个相当好的方法.我个人 ...

  7. windows Docker Desktop 搭建mysql,mssql和redis服务

    其实网上关于docker上搭建mysql的文章已经很多了,只是今晚自己搭建的时候遇到一些问题,记录一下 1.首先是pull image , docker pull mysql 2.启动服务 docke ...

  8. 每天一个linux命令:top

    1.命令简介 top (top) 令经常用来实时监控linux的系统状况,比如cpu.内存的使用,类似于Windows的任务管理器. 2.用法 top -hv | -abcHimMsS -d dela ...

  9. 全面解决.Net与Java互通时的RSA加解密问题,使用PEM格式的密钥文件

    作者: zyl910 一.缘由 RSA是一种常用的非对称加密算法.所以有时需要在不用编程语言中分别使用RSA的加密.解密.例如用Java做后台服务端,用C#开发桌面的客户端软件时. 由于 .Net.J ...

  10. 洛谷P1048 采药

    题目OJ地址 https://www.luogu.org/problemnew/show/P1048 https://vijos.org/p/1104 题目描述辰辰是个天资聪颖的孩子,他的梦想是成为世 ...