自动释放池构造时,会调用objc_autoreleasePoolPush()函数;
自动释放池销毁时,会调用objc_autoreleasePoolPop()函数;
其实就是创建池调用PUSH入栈,释放时调用POP出栈;
AutoreleasePool实际就是一个保存对象指针的栈;
AutoreleasePool的结构就是有多个AutoreleasePoolPage作为节点构成的双向链表‘
每个AutoreleasePoolPage里有一个存放对象指针的栈;这些指针要么是等待释放的对象,要么就是POOL释放池的边界指针;
AutoreleasePool工作原理:
哨兵对象:在POOL池创建时会调用autoreleaseNoPage,此时会在栈里创建一个哨兵对象;
第一个AutoreleasePoolPage大小为4096字节,其中自身占用56个,哨兵对象占用8个,剩余4032个字节 / 8 = 504 个对象;剩余的AutoreleasePoolPage因为无需哨兵对象,所以是4040 / 8 = 505 个对象;
这里牵扯到Runloop,在线程启动时就会创建对应的POOL,在Runloop即将休眠时,会触发kCFRunLoopBeforeWaiting | kCFRunLoopExit;此时为了不占用资源会调用_objc_autoreleasePoolPop()释放旧的释放池;