一·自动释放池(Autoreleasepool)
struct AutoreleasePoolPageData
{
magic_t const magic;
__unsafe_unretained id *next;
pthread_t const thread;
AutoreleasePoolPage *const parent;
AutoreleasePoolPage *child;
depth;
hiwat;
AutoreleasePoolPageData(_next,_thread,AutoreleasePoolPage *_parent,_depth,_hiwat)
:magic(),next(_next),thread(_thread),parent(_parent),child(nil),depth(_depth),hiwat(_hiwat)
}
结构解释:
magic:用来校验AutoreleasePoolPage结构是否完整 //4*4 16字节
next:指向下一个Autorelease对象,初始化时指向begin //8字节
thread:指向当前线程 //8字节
parent:父节点 //8字节
child:子节点 //8字节
depth:深度 //4字节
hiwat:代表high water mark 最大入栈数量标记 //4字节
AutoreleasePoolPage 构造函数-初始化自动释放池
二·自动释放池的压栈
研究自动释放池,主要是搞清楚释放池和对象的关系
在自动释放池的7791源码有如下注释
A thread`s autorelease pool is a stack of pointers.Each pointer is either an object to release,or POOL_BOUNDARY which
is an autorelease pool boundary.
第一步,搞清楚对象的压栈到哪
1.begin
begin()
{
return (id *) ((uint8_t *)this sizeof(*this));
}
压到 (对象地址 自动释放池大小56 )位处
2.end
id *end()
{
return (id *)((uint8_t *)this SIZE);
}
3.empty
return next==begin();
4.full
return next==end();
5.lessThanHalfFull
return (next-begin()<(end()-begin()) / 2);
第二步,压了什么东西
自动释放池的第一页第一个压了一个边界,其余压对象
三·自动释放池出栈
pop()
{
stop = (id *)token;
return popPage(token,page,stop);
}
如何释放
调整双向链表的指针来释放
popPage()
{
obj = *--page->next;
objc_release(obj);
}
释放完调整指针kill()
page=page->parent;
page->child=nil;
析构当前线程
tls_dealloc(void *p)