自动释放池

2022-05-13  本文已影响0人  代码歌

AutoreleasePool的创建和释放

创建

App启动后,苹果在主线程 RunLoop 里注册了两个 Observer,其回调都是
_wrapRunLoopWithAutoreleasePoolHandler()。

第一个 Observer 监视的事件是 Entry(即将进入Loop),其回调内会调用
_objc_autoreleasePoolPush() 创建自动释放池。优先级最高,保证创建释放池发生在其他所有回调之前。

释放

第二个 Observer 监视了两个事件: BeforeWaiting(准备进入休眠)
时调用_objc_autoreleasePoolPop() 和 _objc_autoreleasePoolPush()
释放旧的池并创建新池;

Exit(即将退出Loop) 时调用 _objc_autoreleasePoolPop() 来释放自动释放池。优先级最低,保证其释放池子发生在其他所有回调之后。

在主线程执行的代码,通常是写在诸如事件回调、Timer回调内的。这些回调会被 RunLoop 创建好的 AutoreleasePool 环绕着,所以不会出现内存泄漏,开发者也不必显示创建 Pool 了。

内部实现

@ autoreleasepool {
    //AutoreleasePoolPage是C++类,调用它里面的push方法
    void *ctx = objc_autoreleasePoolPush(){
        void *objc_autoreleasePoolPush(void)
                           
        void *AutoreleasePoolPage::push(void)
     };
 
    //调用AutoreleasePoolPage中的pop函数,一次pop实际上相当于一次批量的pop操作
    objc_autoreleasePoolPop(ctx){
        void objc_autoreleasePoolPop(void *ctxt)
                                  
        AutoreleasePoolPage::pop(void *ctxt)
    };
}

在autoreleasepool中的所有对象,都会添加到自动释放池中,当进行pop之后, autoreleasepool中所有对象都会被发送一次release消息

AutoreleasePoolPage
[obj autorelease]方法实现
AutoreleasePoolPage中Pop方法的实现

runloop将要结束的时候调用AutoreleasePoolPage的pop()方法:

上一篇 下一篇

猜你喜欢

热点阅读