Zombie Objects简介
NSZombie Objects 变量用来调试与内存有关的问题,跟踪对象的释放过程。
开启NSZombie Objects,会用一个僵尸来替换默认的dealloc实现,也就是在引用计数降到0时,会将该对象转换成僵尸对象,这时候对象就变成僵尸对象
僵尸对象的作用是在你向它发送消息时,它会显示一段日志并自动跳入调试器。
启用Zombie Objects检测目的
启用NSZombie Objects检测是让应用直接崩溃掉时,一个错误的内存访问就会变成一条无法识别的消息发送给僵尸对象。僵尸对象会显示接受到得信息,然后跳入调试器,这样你就可以查看到底是哪里出了问题。
开启Zombie Objects
在Xcode -> Edit Scheme -> Memory Management -> Zombie Objects
为什么不默认开启僵尸对象检测呢?
开启僵尸对象检测,每次通过指针访问对象的时候,都会去检查指针指向的对象是否为僵尸对象。所以会影响程序的执行效率,建议关闭。
开启僵尸对象,只释放对象的相关引用,僵尸对象会替换该对象,占用这个对象的地址。
开启Zombie Object后,对象调用dealloc发生的变化
Zombie Objects hook 住了对象的dealloc方法,调用自己的__dealloc_zombie方法来把对象进行僵尸化。
一、__dealloc_zombie实现
- 获取到即将释放的类
- 判断NSZombie类名这个是否存在,不存在这个僵尸类就创建
- 调用objc_destructInstance方法释放该类的相关引用
- 修改对象的isa指针,并指向这个NSZombie类名僵尸类
- 并没有执行free(obj)将释放的类的内存地址释放
二、再次调用已经释放对象的方法
再次调用已经释放对象的方法,其实是已经变成
- 获取调用类名
- 这时候已经变成僵尸类了,判断是否是僵尸类
- 是僵尸类,截取到原类的类名和方法名
- 输入日志
- 结束进程