iOS-空指针,野指针,僵尸对象

浅谈一下空指针,野指针,僵尸对象。

  • 空指针:没有存储任何内存地址的指针,空指针的值是0;

  • 野指针:指针指向的对象已经被释放了;

  • 僵尸对象:指针指向的对象被释放后,所占用的内存没有重新分配给其他对象,此对象就被称为僵尸对象;

示例:

首先先将Xcode的自动引用计数关闭,并且打开僵尸对象的检测。

关闭自动引用计数


自动引用计数关闭.png

打开僵尸对象的检测


Edit Scheme.png

打开僵尸对象的检测.png

创建一个Person类

#import 

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);

结果:

僵尸对象检测.png

注意:记得调试完成,要将僵尸对象检测关闭;

野指针的是如何形成

这里图解一下野指针的是如何形成,直接通过上面的四行代码来解释:

  1. Person *p = [Person new];


    Person对象.png
  2. [p setName:@"hui"];
    Person对象目前还未被释放,即所占用的内存空间,还一直持有着,所以调用setName:没有任何问题;

  3. [p release];
    Person对象调用了release方法,release主要的作用是让对象的引用计数减1。目前的例子该对象的引用计数为1,所以release之后会释放掉该对象。是否释放对象跟引用计数相关。

  4. [p setName:@"li"];
    又调用了一次setName:方法,此时由于Person对象被释放掉了,所以之前Person对象所占用的内存空间可供其他对象所使用。这是继续访问之前的内存空间,就会报野指针错误;

为了预防我们可以将指向Person对象的指针赋值为nil。我们知道给nil调用方法,是不会执行的,也就不会报错。

    Person *p = [Person new];
    [p setName:@"hui"];
    [p release];
    p = nil;
    [p setName:@"li"];

总结

  • 为了防止不小心调用了僵尸对象,可以将对象赋值nil;
  • 对象已经被释放,不要在对该对象执行任何操作;

你可能感兴趣的:(iOS-空指针,野指针,僵尸对象)