iOS-空指针,野指针,僵尸对象
2019-07-08 本文已影响0人
厦门_小灰灰
浅谈一下空指针,野指针,僵尸对象。
-
空指针:没有存储任何内存地址的指针,空指针的值是0;
-
野指针:指针指向的对象已经被释放了;
-
僵尸对象:指针指向的对象被释放后,所占用的内存没有重新分配给其他对象,此对象就被称为僵尸对象;
示例:
首先先将Xcode的自动引用计数关闭,并且打开僵尸对象的检测。
关闭自动引用计数
自动引用计数关闭.png
打开僵尸对象的检测
Edit Scheme.png
打开僵尸对象的检测.png
创建一个Person类
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Person : NSObject
@property (copy, nonatomic) NSString *name;
@end
NS_ASSUME_NONNULL_END
空指针示例
Person *p = nil;
Person *p1 = NULL;
NSLog(@"%@, %p", p, p);
NSLog(@"%@, %p", p1, p1);
打印结果:
2019-07-07 20:18:36.654484+0800 NSThreadDemo[3522:98492] (null), 0x0
2019-07-07 20:18:36.654634+0800 NSThreadDemo[3522:98492] (null), 0x0
野指针示例
Person *p = [Person new];
[p setName:@"hui"];
[p release]; //将p指针指向的对象释放掉
[p setName:@"li"]; //报错了
报错原因:
-[Person setName:]: message sent to deallocated instance 0x6000014d2cd0
给一个已经dealloc的对象发送消息。
僵尸对象示例
前提开始了僵尸对象检测:
Person *p = [Person new];
[p setName:@"hui"];
[p release]; //将p指针指向的对象释放掉
NSLog(@"%@", p.name);
结果:
注意:记得调试完成,要将僵尸对象检测关闭;
野指针的是如何形成
这里图解一下野指针的是如何形成,直接通过上面的四行代码来解释:
-
Person *p = [Person new];
Person对象.png -
[p setName:@"hui"];
Person对象目前还未被释放,即所占用的内存空间,还一直持有着,所以调用setName:没有任何问题; -
[p release];
Person对象调用了release方法,release主要的作用是让对象的引用计数减1。目前的例子该对象的引用计数为1,所以release之后会释放掉该对象。是否释放对象跟引用计数相关。 -
[p setName:@"li"];
又调用了一次setName:方法,此时由于Person对象被释放掉了,所以之前Person对象所占用的内存空间可供其他对象所使用。这是继续访问之前的内存空间,就会报野指针错误;
为了预防我们可以将指向Person对象的指针赋值为nil。我们知道给nil调用方法,是不会执行的,也就不会报错。
Person *p = [Person new];
[p setName:@"hui"];
[p release];
p = nil;
[p setName:@"li"];
总结
- 为了防止不小心调用了僵尸对象,可以将对象赋值nil;
- 对象已经被释放,不要在对该对象执行任何操作;