tags: OC 30 day
Wild Pointer 是什么?
野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)指针变量在定义时如果未初始化,其值是随机的,指针变量的值是别的变量的地址,意味着指针指向了一个地址是不确定的变量,此时去解引用就是去访问了一个不确定的地址,所以结果是不可知的。
C语言中的Wild Pointer:
定义一个指针变量,没有初始化,这个指针变量的值是一个垃圾值,指向一个随机空间,这个指针叫做wild Pointer。
OC中的Wild Pointer:
指针指向的对象已经被回收了。这样的只知叫做wild Pointer。
对象回收的本质
内存回收的本质:
申请一个变量,实际下就是向系统申请指定字节数空间的。这些空间系统就不会再分配给别人了。
当变量被回收的时候,代表变量佔用的字节空间从此以后系统可以分配给别人使用了。
但是字节空间中储存的资料还在,
回收对象:
所谓的对象回收,指的是对象佔用的空间可以分配给别人。
当这个对象佔用的空间没有分配给别人之前,其实对象数据还在。
鉴于以上的知识,请看下面这段程式码。
int main(int argc, char * argv[]) { @autoreleasepool { Person *p1 = [[Person alloc]init]; p1.name = @"猴子"; NSUInteger count = [p1 retainCount]; NSLog(@"count = %lu",count); [p1 release]; [p1 message]; }}
这对程式码会不会crash?
Zombie Objects
一个已经被释放的对象,但是这个对象所佔的空间还没有分配给别人,这样的对象叫做zombie objects。我们透过wild pointer去访问zombie objects 的时候。有可能没问题,也有可能会有问题。当殭尸对象佔用的空间还没有分配给别人的时候,这是可以的。
当殭尸对象佔用的空间分配给别人使用的时候,就不可以。
我们认为只要对象成为了Zombie Objects,无论如何都不要访问了
就希望如果访问的是Zombie Objects,无论如何报错。
Zombie Objects实时检查机制,可以将这个机制打开。打开之后,只要访问殭尸对象,无论空间是否分配,就会报错。
在edit scheme 里面选取run -> Diagnostics 打开 Zombie Objects
为什么不默认打开Zombie Objects对象检测?
一但打开Zombie Objects检测,那么在每访问一个对象的时候,都会先检查这个对象是否为一个Zombie Objects对象。这样是极其消耗性能的。
使用wild pointer 访问 zombie objects就会报错,如何避免zombie objects 对象错误。
当一个指针称为野指针以后,将这个指针的值设为nil。
int main(int argc, char * argv[]) { @autoreleasepool { Person *p1 = [[Person alloc]init]; p1.name = @"猴子"; NSUInteger count = [p1 retainCount]; NSLog(@"count = %lu",count); [p1 release]; p1 = nil; [p1 message]; }}
当一个指针的值为nil,通过这个指针去调用对象发法的时候(包括点语法),不会报错。只是没有任何反应。但是如果直接访问属性,就会报错。
殭尸复活
以下程式码是无法使用的,因为殭尸是无法复活的,因为他已经火化了。
int main(int argc, char * argv[]) { @autoreleasepool { Person *p1 = [[Person alloc]init]; p1.name = @"猴子"; NSUInteger count = [p1 retainCount]; NSLog(@"count = %lu",count); [p1 release]; [p1 retain]; }}