AutoreleasePool什么时候释放

Autorelease对象什么时候被释放?

源码地址

在没有手动添加AutoreleasePool的情况下,Auturelease对象是在当前的runloop迭代结束的时候进行释放;而它能否释放的原因是系统在每个runloop的迭代中都加入了自动释放池的push和pop。

ARC下,使用@autoreleasepool{}来使用一个AutoreleasePool,随后编译器将其修改为下面的样子:

void *context = objc_autoreleasePoolPush();

//{}中的代码

objc_autoreleasePoolPop(context)

这两个函数都是对AutoreleasePoolPage的简单封装,所以自动释放机制的核心就在与AutoreleasePoolPage这个类。

AutoreleasePool类结构

AutoreleasePool实际上是一个典型的双链表结构,每个page的大小为4096Byte;

自动释放池的工作过程:

void *objc_autoreleasePoolPush()内部实际调用的是AutoreleasePoolPage::push()函数,其实现如下:

push函数实现

hotPage()是找出当前正在使用的Page,第一次调用时hotPage为NULL,所以会新建一个parent=NULL的AutoreleasePoolPage对象作为自动释放池加入到栈中,并将其设置为hopPage,然后返回POOL_SENTINEL的地址赋值给main()函数里的变量__autoreleasepool;

然后将一个哨兵对象POOL_SENTINEL压入栈顶,即调用,即调用autoreleaseFast(POOL_SENTINEL)

autoreleaseFast函数

添加对象进入到自动释放池

可以看出,当前有page并且没有满,则直接将对象入栈顶(page->add(obj))

add函数

将对象压入栈顶,然后将栈顶指针下移;

如果当前page已满,则调用autoreleaseShow

autoreleaseShow函数

基本逻辑:如果page不存在则,创建新的自动释放池(PoolPage),并将对象加进池子;如果已经存在自动释放池在栈中,且hotPage满了,则遍历其子page,如果存在没满(page->full()==NO)的子page,则将该子page设置为hotPage,否则如果都满了,则以最后一个子page为父page,新建一个page,插入当前的page链表,同样设置该新建的page为hotPage,然后将自动释放对象加入page;

销毁自动释放池

void AutoreleasePoolPage::pop(void *token)

此处的token参数,即push()的返回值,实际上就是POOL_SENTINEL的地址;通过该地址即可找到所在Page的地址指针

pop函数

该过程主要分为两步:

1,page->releaseUntil(stop); //对自动释放池中对象调用objc_release()进行释放,对栈顶到POOL_SENTINEL之间的所有对象调用objc_release(),进行引用计数减1;

2,page->kill(); //清空page对象

注意函数中的注释:

// memory: delete empty children

// hysteresis: keep one empty child if this page is more than half full

// special case: delete everything for pop(0)

保持一个空的子page当当前page大于一半时(可能是为了马上要新建page节省开销)

当调用pop(0)时,会清理掉所有的page; 

if (page->child) {

          if (page->lessThanHalfFull()) {

              page->child->kill(); //如果当前存放的对象少于一半全部删除

          }

          else if (page->child->child) {

              page->child->child->kill();//存放对象多余一半,则保留一个子page,节省开销

          }

      }

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 人过中年,能让你挥霍的时间少之又少。不矫情、不做作、不畏惧别人的目光,想要的东西就去争取,得不到的东西就断舍离。 ...
    一生追梦的人阅读 3,211评论 0 0
  • 是谁带来远古的呼唤,是谁留下千年的祈盼,难道说还有无言的歌,还是那久久不能忘怀的眷恋。哦~我看见一座座山,一座座山...
    文真阅读 2,972评论 0 0
  • 叶子总喜欢邀我到她家去玩,尤其是在晚上的时候。 叶子骗了我,她说,晚上会送我回家。可是,玩得太晚,她自...
    火山361阅读 1,319评论 0 1
  • 夜色里 你以一抹微笑泛舟 泛舟在我蓝色的心河 星空 洒落一片如雨的花瓣 掩映你如火的容颜 风 缠绵地跟着水儿打转 ...
    当风起时边走边记阅读 2,726评论 0 3

友情链接更多精彩内容