文章目录
1. 自动释放池
查看CPP代码
自动释放池 ,
进入大括号的时候,创建一个obj;
然后括号里面创建的对象都会被自动添加autorelease(ARC),被push到池中;
在出了大括号后,把自动释放池内添加的对象进行释放

- 自动释放池主要的底层数据结构是
__AtutoreleasePool , AutoreleasePoolPage
2. AutoreleasePoolPage的结构

- next : 执行下一个存储位(下一个能放autorelease对象地址的区域)
next = begin 说明page是空的
next = end 说明page是 满的(fullpage)
- 调用push方法会将一个POOL_BOUNDARY入栈,并返回其存放的内存地址
- hotPage
当前正在使用的page
- coldPage
不被使用的page,一般是因为已经被装满了.
一个page会有一定的空间(4096-56)来装入对象,当page的空间还没有 满,还可以被装入对象时,这个page就是hotPage;表明再有对象要被装入,就会装到这个Page中,
如果这个page被装满了,next会=end,同时创建一个新的poolPage2,page的child指向这个新的poolPage2. page会变成coldpage,新的poolPage2成为hotPage.
以后再有什么操作,都会从这个hotpage开始.比如pop,addObj,push
3. 源码
1. push()
- 这里的push 只是大括号开始时push,会向里面入栈一个POOL_BOUNDARY
- add(obj)也相当于入栈POOL_BOUNDARY
obj 指向的地址也就是POOL_BOUNDARY的地址
POOL_BOUNDARY : 自动释放池的边界
2. autorelease
- 往pool中添加对象 , ARC下 自动释放池找那个创建的对象会被自动添加autorelease
3. pop()

从hotPage , --page->next 来获取对象,然后release
4. Runloop & autoreleasepool
- iOS在主线程的runloop中注册了两个observer
- 第一个observer :
- 监听了KCFRunLoopEntry时间,会调用objc_autoreleasePoolPush()
- 第二个observer :
- 监听了KCFRunLoopBeforeWaiting事件,会调用objc_autoreleasePoolPop(),objc_autoreleasePoolPush()
- 监听了KCFRunLoopBeforeExit事件,会调用objc_autoreleasePoolPop()
这样push 和 pop 就会形成一个闭环,确保成对出现.
本文详细解析Objective-C中的自动释放池(AutoreleasePool)工作原理,包括AutoreleasePoolPage的结构、push和pop操作,以及Runloop如何与autoreleasepool协同工作。通过源码分析,阐述了对象在自动释放池中的生命周期和内存管理机制。






2075

被折叠的 条评论
为什么被折叠?



