iOS内存管理01 -- 引用计数器

什么是内存管理

  • 移动设备的内存极其有限,每个App所能占用的内存是有限制的;
  • 当APP所占用的内存较多时,系统会发出内存警告,这时得回收一些不需要再使用的内存空间,比如回收一些不需要再使用的对象,变量等。
  • 管理范围:任何继承了NSObject的对象,对于其他基本数据类型是无效的。
  • 每个OC对象都有自己的引用计数器,是一个整数,表示对象被引用的次数,即有多少外界对象正在使用这个OC对象;

引用计数器的作用

  • 当使用alloc,new,copy创建一个新对象时,新对象的引用计数器默认就是1;
  • 当一个对象的引用计数器值为0时,对象占用的内存就会被系统回收,换句话说,如果对象的引用计数器不为0,那么在整个程序运行过程中,它占用的内存就不可能被回收,除非整个程序已经退出。

引用计数器的操作

  • 给对象发送一条retain消息,对象的引用计数器值+1;
  • 给对象发送一条release消息,对象的引用计数器值-1;
  • 给对象发送retainCount消息,可以获得对象引用计数器值。

对象的销毁

  • 当一个对象的引用计数器值为0时,那么它将被销毁,其占用的内存被系统回收;
  • 当一个对象被销毁时,系统会自动向对象发送一条dealloc消息;
  • 一般会重写dealloc方法,在这里释放相关资源,dealloc就相当于对象的遗言;
  • 在MRC环境重写dealloc方法,内部一定要调用[super dealloc]。
  • MRC环境设置操作如下:
Snip20210428_77.png

测试代码:命令行工程,MRC内存环境

#import 
#import "YYPerson.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        YYPerson *person = [[YYPerson alloc]init];//+1 = 1
        NSLog(@"引用计数器 count = %lu",[person retainCount]);
        
        [person retain];//+1 = 2
        NSLog(@"引用计数器 count = %lu",[person retainCount]);
        
        [person release];//-1 = 1
        NSLog(@"引用计数器 count = %lu",[person retainCount]);
        
        [person release];//-1 = 0 且被销毁,内存被回收,会调用dealloc方法
        [person release]
        //当person指针的指向依然指向person对象这块已经被回收的内存空间
        //如果再向这块内存发送消息,即向僵尸对象发送消息,会报错,也就是所谓的野指针错误。
        //只有将person指针置为nil,即空指针,在OC中向空指针发送消息不会报错。
    }
    return 0;
}
  • alloc一个person对象,并且用一个指针变量(YYPerson *person)指向person对象,此时person对象的引用计数器值为1;
  • [person retain]给person对象发送一条retain消息,此时person对象的引用计数器值+1,其值为2;
  • [person release]给person对象发送一条release消息,此时person对象的引用计数器值-1,其值为1;
  • 再次执行 [person release],此时person对象的引用计数器值-1,其值为0;我们知道一旦对象的引用计数器值为0,就会自动被系统销毁回收,变成僵尸对象,不可访问的对象;
  • 再次执行 [person release],会报错,因为向僵尸对象发送消息会造成EXC_BAD_ACCESS崩溃,也就是通常所说的野指针错误。
  • person对象已经被销毁了成了僵尸对象,但是指针变量(YYPerson *person)依然指向person对象内存地址,即指向了一块被系统回收的不可用内存,为了防止向僵尸对象发送消息,需要将指针变量(YYPerson *person)置为nil,即所谓的空指针,在OC中向空指针发送消息是不会报错的。
  • 野指针:指向僵尸对象(不可用内存,被系统回收的内存)的指针。
  • 空指针:指向nil的指针。
  • 僵尸对象:已经被系统回收内存的对象,不可用对象,访问就会报错。

开启僵尸对象的监控

  • Edit-Scheme -->Diagnostics --> Memory Management --> Zoomble Objects

你可能感兴趣的:(iOS内存管理01 -- 引用计数器)