关于autorelasepool的理解

Posted kaisi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于autorelasepool的理解相关的知识,希望对你有一定的参考价值。

1.autorelasepool内存放的是autorelase对象,能够做到延迟调用relase。

2.autorelasepool是通过以 AutoreleasePoolPage 为结点的双向链表来实现的,AutoreleasePoolPage内部数据结构有这些

      技术分享图片

  magic 用来校验 AutoreleasePoolPage 的结构是否完整;

  next 指向最新添加的 autoreleased 对象的下一个位置,初始化时指向 begin() ;

  thread 指向当前线程;

  parent 指向父结点,第一个结点的 parent 值为 nil ;

  child 指向子结点,最后一个结点的 child 值为 nil ;

  depth 代表深度,从 0 开始,往后递增 1;

  hiwat 代表 high water mark 

  当next指向begin时代表该page为空,当next指向end时代表page已满。

3.autorelasepool通过push函数->autorelaseFast->add(obj)方法进项对象的压栈操作

static inline id *autoreleaseFast(id obj)
{
    AutoreleasePoolPage *page = hotPage();
    if (page && !page->full()) {
        return page->add(obj);
    } else if (page) {
        return autoreleaseFullPage(obj, page);
    } else {
        return autoreleaseNoPage(obj);
    }
}

  当前 page 存在且没有满时,直接将对象添加到当前 page 中,即 next 指向的位置;

  当前 page 存在且已满时,创建一个新的 page ,并将对象添加到新创建的 page 中;

  当前 page 不存在时,即还没有 page 时,创建第一个 page ,并将对象添加到新创建的 page 中。

3.autorelasepool通过-[NSAutoreleasePool release] -> AutoreleasePoolPage::pop(void *)调用过程执行autorelase对象的relase操作。

4.autorelasepool通过调用AutoreleasePoolPage的push函数为池中添加autorelase对象,一个push操作即为创建一个autorelasepool,然后在AutoreleasePoolPage的next位置插入一个POOL_SENTINEL,并返回其地址代表该pool的token,作为之后pop操作的入参。之后每次通过autorelase方法想该双向链表即page插入autorelase对象,即next指向该对象,依次完成。pop操作时,内存地址在 pool token 之后的所有 autoreleased 对象都会被 release 。直到 pool token 所在 page 的 next 指向 pool token 为止。

5.autorelasepool与runloop都是和线程有关,每一个线程都会维护自己的自动释放池堆栈,每一个自动释放池都对应一个线程。

以上是关于关于autorelasepool的理解的主要内容,如果未能解决你的问题,请参考以下文章

关于CSS的个人理解

金蝶handler中 collection 代码片段理解

关于代码片段的时间复杂度

调用模板化成员函数:帮助我理解另一个 *** 帖子中的代码片段

#yyds干货盘点# Java | 关于synchronized相关理解

如何理解这段代码片段中的两对括号?