iOS之Zombie Objects检测僵尸对象原理

Zombie Objects简介

NSZombie Objects 变量用来调试与内存有关的问题,跟踪对象的释放过程。

开启NSZombie Objects,会用一个僵尸来替换默认的dealloc实现,也就是在引用计数降到0时,会将该对象转换成僵尸对象,这时候对象就变成僵尸对象

僵尸对象的作用是在你向它发送消息时,它会显示一段日志并自动跳入调试器。

启用Zombie Objects检测目的

启用NSZombie Objects检测是让应用直接崩溃掉时,一个错误的内存访问就会变成一条无法识别的消息发送给僵尸对象。僵尸对象会显示接受到得信息,然后跳入调试器,这样你就可以查看到底是哪里出了问题。

开启Zombie Objects

在Xcode -> Edit Scheme -> Memory Management -> Zombie Objects

开启Zombie Objects检测.png

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

开启僵尸对象检测,每次通过指针访问对象的时候,都会去检查指针指向的对象是否为僵尸对象。所以会影响程序的执行效率,建议关闭。
开启僵尸对象,只释放对象的相关引用,僵尸对象会替换该对象,占用这个对象的地址。

开启Zombie Object后,对象调用dealloc发生的变化

Zombie Objects hook 住了对象的dealloc方法,调用自己的__dealloc_zombie方法来把对象进行僵尸化。

一、__dealloc_zombie实现

__dealloc_zombie.png
  • 获取到即将释放的类
  • 判断NSZombie类名这个是否存在,不存在这个僵尸类就创建
  • 调用objc_destructInstance方法释放该类的相关引用
  • 修改对象的isa指针,并指向这个NSZombie类名僵尸类
  • 并没有执行free(obj)将释放的类的内存地址释放

二、再次调用已经释放对象的方法

调用已经释放的类.png

再次调用已经释放对象的方法,其实是已经变成

  • 获取调用类名
  • 这时候已经变成僵尸类了,判断是否是僵尸类
  • 是僵尸类,截取到原类的类名和方法名
  • 输入日志
  • 结束进程
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容