iOS之AutoreleasePool

AutoreleasePool底层涉及的数据结构:__AtAutoreleasePoolAutoreleasePoolPage

调用了autorelease的对象最终都是通过AutoreleasePoolPage对象来管理的。

AutoreleasePoolPage结构

  • 每个AutoreleasePoolPage对象占用4096个字节

  • 存放Page自身的成员变量autorelease对象

  • Page自身是结构

  • Page与Page之间通过parentchild指针连接成双向链表

AutoreleasePool的实现原理:

AutoreleasePool底层是个结构体__AtAutoreleasePool,包含有pushpop两个方法(objc_autoreleasePoolPushobjc_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语句以销毁它