@autoreleasePool = __AtAutoreleasePool __autoreleasePoolc++
__AtAutoreleasePool 结构体
复制代码
AutoreleasePool 是 oc 的一种内存回收机制,正常状况下变量在超出做用域的时候 release,可是若是将变量加入到 pool 中,那么release 将延迟执行objective-c
AutoreleasePool 并无单独的结构,而是由若干个 AutoreleasePoolPage 以**双向链表**形式组成
1. PAGE_MAX_SIZE :4KB,虚拟内存每一个扇区的大小,内存对齐
2. 内部 thread ,page 当前所在的线程,AutoreleasePool是按线程一一对应的
3. 自己的成员变量占用56字节,剩下的内存存储了调用 autorelease 的变量的对象的地址,同时将一个哨兵插入page中
4. pool_boundry 哨兵标记,哨兵其实就是一个空地址,用来区分每个page 的边界
5. 当一个Page被占满后,会新建一个page,并插入哨兵标记
复制代码
单个自动释放池的执行过程就是objc_autoreleasePoolPush()
—> [object autorelease]
—> objc_autoreleasePoolPop(void *)
markdown
具体实现以下:oop
void *objc_autoreleasePoolPush(void) {
return AutoreleasePoolPage::push();
}
void objc_autoreleasePoolPop(void *ctxt) {
AutoreleasePoolPage::pop(ctxt);
}
复制代码
内部其实是对 AutoreleasePoolPage 的调用ui
每当自动释放池调用 objc_autoreleasePoolPush 时,都会把边界对象放进栈顶,而后返回边界对象,用于释放。spa
AutoreleasePoolPage::push();
调用👇线程
static inline void *push() {
return autoreleaseFast(POOL_BOUNDARY);
}
复制代码
autoreleaseFast
👇指针
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);
}
}
复制代码
👆上述方法分三种状况选择不一样的代码执行:code
- 有 hotPage 而且当前 page 不满,调用 page->add(obj) 方法将对象添加至 AutoreleasePoolPage 的栈中
- 有 hotPage 而且当前 page 已满,调用 autoreleaseFullPage 初始化一个新的页,调用 page->add(obj) 方法将对象添加至 AutoreleasePoolPage 的栈中
- 无 hotPage,调用 autoreleaseNoPage 建立一个 hotPage,调用 page->add(obj) 方法将对象添加至 AutoreleasePoolPage 的栈中
最后的都会调用 page->add(obj) 将对象添加到自动释放池中。 hotPage 能够理解为当前正在使用的 AutoreleasePoolPage。
复制代码
是以栈的形式存在,而且内部对象经过进栈、出栈对应着 objc_autoreleasePoolPush 和 objc_autoreleasePoolPop
当咱们对一个对象发送一条 autorelease 消息时,其实是将这个对象地址加入到 autoreleasePoolPage 的栈顶 next 指针的指向的位置
复制代码
iOS 在主线程注册了两个 observerorm
__第一个observer __
监听了 kCFRunloopEntry, 会调用 objc_autoreleasePool_push()
第二个 observer
监听了 kCFRunloopBeforeWaiting 会调用 objc_autoreleasePool_pop() 、objc_autoreleasePool_push()
监听了 kCFRunloopExit 事件,会调用 objc_autoreleasePool_pop()