自动释放池的原理和本质

自动释放池的原理和本质

什么是 autoreleasepool?

答:autoreleasepoolOC 的内存自动管理机制,它可以通过把不需要立即释放的对象通过栈的形式放到自动释放池中,当代码执行到释放池作用域结束,将池中的对象统一发送 release 消息,当对象的引用计数为零时,对象就被释放,内存被系统回收.

autoreleasepool 的本质其实也是一个对象,

struct __AtAutoreleasePool {
    //构造函数
    __AtAutoreleasePool() {
        atautoreleasepoolobj = objc_autoreleasePoolPush();
    }
    //析构函数
    ~__AtAutoreleasePool() {
        objc_autoreleasePoolPop(atautoreleasepoolobj);
    }
    // 结构体定义的对象
    void * atautoreleasepoolobj;
};

@autoreleasepool {}
//等价于
{__AtAutoreleasePool __autoreleasepool; }
  • __AtAutoreleasePool是一个结构体,有构造函数和析构函数

  • autoreleasepool在加入要释放的对象时,底层调用的是objc_autoreleasePoolPush方法

  • autoreleasepool在调用析构函数释放时,内部的实现是调用objc_autoreleasePoolPop方法

  • 栈为节点,通过双向链表构成

不手动指定autoreleasepool的前提下,一个autorealese对象在什么时刻释放?(比如在一个vc的viewDidLoad中创建)

  • 分两种情况:手动干预释放时机、系统自动去释放

    • 手动干预释放时机:指定autoreleasepool就是所谓的:当前作用域大括号结束时就立即释放

    • 系统自动去释放:不手动指定autoreleasepoolAutorelease对象会在当前的 runloop 迭代结束时释放,下面详细说明释放时机

    • RunLoop中的三个状态会处理自动释放池,通过打印代码发现有两个Observer监听到状态值为:1和160(32+128)

      • kCFRunLoopEntry(1) // 第一次进入会创建一个自动释放池
      • kCFRunLoopBeforeWaiting(32) // 进入休眠状态前先销毁自动释放池,再创建一个新的自动释放池
      • kCFRunLoopExit(128) // 退出RunLoop时销毁最后一次创建的自动释放池
  • 在每一次runloop循环将要结束时,会对前一次创建的AutoreleasePool进行pop操作,同时会push进来一个新的AutoreleasePool,所以在viewDidLoad中所创建的array对象,是在当次runloop将要结束的时候,调用AutoreleasePoolPagepop方法中释放的

你可能感兴趣的:(自动释放池的原理和本质)