iOS技巧

如何检测野指针?

2019-05-10  本文已影响71人  往事不许提

啥是野指针?

如何定位野指针

1.内存涂鸦(Malloc Scribble)
Xcode提供的Malloc Scribble,可以将对象释放后在内存上填上不可访问的数据,将随机发生变成不随机发生的事情,选中Product->Scheme->Edit Scheme ->Diagnostics – >勾选 Malloc Scribble项,结果如下:

271cfd6e1028f577e5dd49e4e3f593db.png

设置了Enable Scribble,在对象申请内存后在申请的内存上填0xaa,内存释放后在释放的内存上填0x55;如果内存未被初始化就被访问,或者释放后被访问,Crash必现。
Warning:该方法必须连接Xcode运行代码才能发现,并不适合测试人员使用。

  1. 僵尸对象(NSZombieEnabled)
unrecognized selector sent to instance  .

默认情况下. Xcode不会去检测指针指向的对象是否为1个僵尸对象. 能访问就访问 不能访问就报错.

// 首先判断对象a是否还存在,如存在,执行mehtod方法;若不存在,此时就是对象a就是僵尸对象,此时如果不判断直接调用method方法,就会crash
if(!a){
   a = [[A alloc] init];
}
[a method];

Xcode提供的NSZombieEnabled,通过生成僵尸对象来替换dealloc的实现,当对象引用计数为0 的时候,将需要dealloc的对象转化为僵尸对象。如果之后再给这个僵尸对象发消息则抛异常。先选中Product -> Scheme -> Edit Scheme -> Diagnostics -> 勾选Zombie Objects 项,显示如下:

72537f67f7ad85f98f22adc17fb9d06b.png

然后在Product -> Scheme -> Edit Scheme -> Arguments设置NSZombieEnabled、MallocStackLoggingNoCompact两个变量,且值均为YES。显示如下:


3f07ccbc098736b06caab7cd4e3715fd.png

注意:发版前要将僵尸对象检测这些设置都去掉,否则每次通过指针访问对象时,都去检查指针指向的对象是否为僵尸对象,这就影响效率了。

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

因为一旦开启,每次通过指针访问对象的时候.都会去检查指针指向的对象是否为僵尸对象.
那么这样的话 就影响效率了.

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

如何定位Obj-C野指针随机Crash(一):先提高野指针Crash率
如何定位Obj-C野指针随机Crash(二):让非必现Crash变成必现
如何定位Obj-C野指针随机Crash(三):加点黑科技让Crash自报家门

上一篇 下一篇

猜你喜欢

热点阅读