深入解析自动释放池AutoreleasePool
2021-09-09 本文已影响0人
里克尔梅西
文章:
https://www.jianshu.com/p/7bd2f85f03dc
原理
-
__AtAutoreleasePool 双向链表结构
-
构造函数内部调用:objc_autoreleasePoolPush()方法,返回边界对象atautoreleasepovolobj
-
析构函数内部调用:objc_autoreleasePoolPop()方法,传入边界对象atautoreleasepoolobj
-
每一个poolPage是4096字节,有个child有个parent,有个id next指向下一个地址
-
除了前面的56个固定字节,后面4040个字节存放对象,每8个字节一个对象
-
调用objc_autoreleasePoolPush的时候,先有个哨兵对象POOL_BOUNDARY被放到栈顶
-
调用objc_autoreleasePoolPop的时候,先根据传入的边界对象地址找到边界对象所处的page;然后选择当前page中最新加入的对象一直向前清理,可以向前跨越若干个page,直到边界所在的位置;清理的方式是向这些对象发送一次release消息,使其引用计数减一
与Runloop关系
- App启动后,苹果在主线程RunLoop里注册了两个Observer
- 第一个Observer监视的事件是Entry(即将进入Loop),其回调内会调用 _objc_autoreleasePoolPush()创建自动释放池。
- 第二个Observer监视了两个事件BeforeWaiting(准备进入休眠)时调用_objc_autoreleasePoolPop()和_objc_autoreleasePoolPush()释放旧的池并创建新池;Exit(即将退出Loop) 时调用 _objc_autoreleasePoolPop()来释放自动释放池
AutoreleasePool需要手动添加的情况
- 通过循环方式创建大量临时对象;