在 iOS 中,autoreleasepool
的底层实现基于 Objective-C 运行时(runtime)和内存管理机制。
图解说明
-
Objective-C Runtime 和 Autoreleasepool 的创建
在 Objective-C 中,每次进入一个
@autoreleasepool
块时,都会创建一个AutoreleasePool
对象,这个对象会被加入到当前线程的AutoreleasePoolStack
中。---------------------- | AutoreleasePoolStack | |----------------------| | AutoreleasePool | <-- 新创建的 pool |----------------------| | AutoreleasePool | <-- 之前的 pool ----------------------
-
对象的 autorelease
当对象调用
autorelease
方法时,它会被添加到当前的AutoreleasePool
中,而不是立即被释放。NSObject *obj = [[NSObject alloc] autorelease];
这时,
obj
被加入到当前线程的AutoreleasePool
对象列表中。AutoreleasePool ----------------- | obj | | obj2 | | obj3 | -----------------
-
AutoreleasePool 的销毁
当离开
@autoreleasepool
块时,当前的AutoreleasePool
对象会被销毁,并且池中的所有对象都会接收到release
消息。@autoreleasepool { NSObject *obj = [[NSObject alloc] autorelease]; // do something } // 此处 `obj` 被释放
销毁时,
AutoreleasePool
中的每个对象都会执行release
操作。obj1.release() obj2.release() obj3.release()
底层实现细节
-
AutoreleasePoolPage
AutoreleasePool
实际上是由多个AutoreleasePoolPage
组成,每个页面大小固定,使用链表链接。每当一个页面填满时,会创建一个新的页面。--------------------- | AutoreleasePoolPage| |--------------------| | obj1 | | obj2 | | ... | |--------------------| --> Next Page | objN | |--------------------|
-
AutoreleasePoolPage::push 和 pop
在
@autoreleasepool
块开始时,会调用push
方法创建一个新的页面,并将其加入到链表中。在块结束时,调用pop
方法从当前页面开始清理对象,并释放页面。AutoreleasePoolPage *page = new AutoreleasePoolPage(); page->push(); // 在块结束时 page->pop();
通过这种方式,autoreleasepool
实现了自动管理内存释放,减少了开发者手动管理内存的负担,同时确保了内存的高效使用。