之前跟同事讨论过一个问题:
开启子线程
是否会自动创建一个默认的自动释放池?
根据StackOverFlow
上这篇问答所讨论:
在当前线程第一次发送autorelease时,
会进行自动释放池的创建,
因而不会造成内存泄漏。
个人认为这个特性可以看做是自动释放池的懒加载
。
从源码处(版本:objc4-723
)可论证一下:
在对一个对象发送autorelease
消息时,运行时会调用以下c函数:
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);
}
}
逻辑很清晰:
- 首先获取当前线程的
hot page
,即自动释放池页栈栈顶位置的那一页; - 然后判断是否存在此
hot page
,若存在并当前页未满,则直接将该对象指针入池; - 若存在并栈已满,则需要调用
autoreleaseFullPage
用于开辟新页并入池; - 若不存在
hot page
(no page
,在源码中注释为"No page" could mean no pool has been pushed or an empty placeholder pool has been pushed and has no contents yet
),即当前线程还没有建立自动释放池或只有一个placeholder pool
,则需要调用autoreleaseNoPage
用于新建一个自动释放池页栈并入栈一页。
因此问答上讨论的逻辑应该是正确的,但如果子线程全程未使用任何autorelease
对象的话,应该不会建立自动释放池。
网友评论