关于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的理解的主要内容,如果未能解决你的问题,请参考以下文章
调用模板化成员函数:帮助我理解另一个 *** 帖子中的代码片段