iOS 野指针与僵尸对象

前言

野指针就像是代码中的炸弹,它的存在会导致很多隐患,因为不知道什么时候就会触发。在开发中经常会发生莫名其妙的crash,很多情况下就是野指针造成的。

  • 野指针
    野指针和空指针是不一样的,空指针没有储存任何的内存地址,而野指针指向的一块内存地址,但是该内存不可用。换句话说,野指针指向的对象已经被释放了。
Person *p =[[Person alloc]init];
[p setName:@"wang"];
[p release]; //指针p指向的对象已经被释放,但是该指针还能访问该内存地址
[p setName:@"zhao"]; //所以此处不会报错

但是这是存在隐患的,这种情况下被释放掉的对象就会成为僵尸对象。僵尸对象很可能会导致代码crash。

  • 僵尸对象
    在OC中,对象被释放后所占用的内存在没有被复写(重新分配给其他对象)前称为僵尸对象,这是野指针是可以访问该内存的,因为对象的数据还在,所以程序不会报错。但是该内存一旦重新分配给其他对象就会出现问题。

  • 检测僵尸对象
    所以虽然可以通过野指针去访问已经被释放的对象,但是我们不允许这么做。
    在编码的时候就要去检测僵尸对象。


    1.png
2.png

这样在[person release]之后

person对象被释放了,由于scheme开启了僵尸对象选项,所以person对象在释放时调用的dealloc方法在底层被swizzle了

dealloc方法执行时,代码走的并不是清理资源,回收内存。而是copy了一个NSZombie对象模版,并修改zimbie对象的isa指针,形成了一个新的僵尸对象类_NSZombie_Person。所以在[person release];执行之后, 打印的person对象类型为_NSZombie_Person

_NSZombie_Person类中只有一个isa指针,里面没有其他的属性和方法,所以不能响应任何事件,所以在向这个僵尸对象发送消息时,就会报错,并打印出来。这非常有利于调试。

  • 避免野指针
    很简单,在realase之后将指针指向nil即可。
p = nil;

之后该指针就不能访问到僵尸对象了。

参考资料:一起来构建NSZombie

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • //--------------------内存管理 内存管理范围: 管理任何继承NSObject的对象,基本数据...
    指尖猿阅读 760评论 0 1
  • 内存管理的基本范围和概念. 程序运行过程中药创建大量的对象, 和其他高级语言类似,在ObjC中对象存储在堆区,程序...
    ValienZh阅读 916评论 0 2
  • 1、写一张A1便签:回忆你最近向别人提问为什么的经历,想想当初你是怎么问的,提问的效果怎么样;或者是别人向提你问,...
    venury阅读 190评论 1 0
  • (一) 如果说二十岁出头的人是初尝人生滋味的话,那十几岁的毛头小子、姑娘...
    钰子阅读 317评论 0 0