现在我们已经进入了ARC时代,编译器帮我们在编译代码时自动对变量进行内存管理,使开发者不用再为了对象因为内存管理问题而头疼。AutoreleasePool是自动释放池,当我们在使用@autoreleasepool块时,自动释放池将会对池内对象进行管理,直到变量不被使用时,将其内存进行回收。
一、调用源码
struct __AtAutoreleasePool {
__AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}
~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}
void * atautoreleasepoolobj;
};
__AtAutoreleasePool __autoreleasepool;
分析:当使用clang编译后我们可以看到生成了runtime源码,__AtAutoreleasePool是一个结构体,包含了一个objc_autoreleasePoolPush操作和一个析构函数,函数里调用的是objc_autoreleasePoolPop操作。
二、Push操作
static inline void *push()
{
id *dest;
dest = autoreleaseFast(POOL_BOUNDARY);
return dest;
}
autoreleaseFast实现
static inline id *autoreleaseFast(id obj)
{
AutoreleasePoolPage *page = hotPage();
if (page && !page->full()) {
return page->add(obj);
} else if (page) {
return autoreleaseFullPage(obj, page);
} else {
return autoreleaseNoPage(obj);
}
}
AutoreleasePool没有单独的内存结构,而是以AutoreleasePoolPage为结点的双向链表将对象进行存放,通过NSObject.mm源码我们知道:
- 每一个AutoreleasePool就是一个指针堆栈,存放着需要进行内存管理的对象或变量;
- 生成的每个AutoreleasePoolPage结点以POOL_BOUNDARY为起点标识,POOL_BOUNDARY即为nil;
- 每