iOS之AutoreleasePool
AutoreleasePool底层涉及的数据结构:__AtAutoreleasePool
和AutoreleasePoolPage
调用了autorelease
的对象最终都是通过AutoreleasePoolPage
对象来管理的。
AutoreleasePoolPage
结构
每个
AutoreleasePoolPage
对象占用4096个字节存放Page自身的成员变量和
autorelease对象
Page自身是栈结构
Page与Page之间通过
parent
和child
指针连接成双向链表
AutoreleasePool的实现原理:
AutoreleasePool底层是个结构体__AtAutoreleasePool
,包含有push
和pop
两个方法(objc_autoreleasePoolPush
和objc_autoreleasePoolPop
):
@autoreleasePool
开始的位置,调用push()
方法:该方法返回一个地址值PoolBoundary
,表示autoreleasePoolPage中存放autorelease对象
的起始位置(也就是从PoolBoundary下一个位置开始存对象);- 在
@autoreleasePool
结束的位置,调用pop(address)
方法:该方法入参PoolBoundary,表示从AutoreleasePoolPage
栈顶开始,向栈上的autorelease对象
发送release消息
,直到遇到PoolBoundary为止,表示当前这个autoreleasePool中的autorelease对象
已被释放完毕。
RunLoop和Autorelease
autorelease对象是什么时候调用release方法的?
iOS在主线程的RunLoop注册了两个Observer:
第一个Observer:监听了kCFRunLoopEntry
事件,会调用objc_autoreleasePoolPush()
第二个Observer:
- 监听了
kCFRunLoopBeforeWaiting
事件,监听到事件时会调用objc_autoreleasePoolPop()
和objc_autoreleasePoolPush()
方法 - 监听了
kCFRunLoopExit
事件,监听到事件时会调用objc_autoreleasePoolPop()
所以在RunLoop进入休眠状态或退出时会对autorelease对象
发送release消息
。
方法内部的局部对象,出了方法后会立即释放吗?
- 会
- 在ARC中,如果在某个方法内创建了一个对象,前端编译器会在方法末尾自动插入release语句以销毁它