文章目录
- autoreleasepool 的功能、特性,用法都在之前内存管理的文章中说过了,这篇博客主要站在源码的角度来分析一下 autoreleasepool 到底是什么。
autoreleasepool究竟是什么
新建一个iOS项目,用clang重写一下main.m(在命令行中使用 clang -rewrite-objc main.m
让编译器重新改写这个文件)。在main.cpp文件的最后,看到main函数变成了这样:
// 原本iOS项目的main.m
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
//clang重新改写以后的main.m
int main(int argc, char * argv[]) {
/* @autoreleasepool */ {
__AtAutoreleasePool __autoreleasepool;
return UIApplicationMain(argc, argv, __null, NSStringFromClass(((Class (*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("AppDelegate"), sel_registerName("class"))));
}
}
也就是说 @autoreleasepool {}
被转换为一个 __AtAutoreleasePool
结构体:
{
__AtAutoreleasePool __autoreleasepool;
}
为了弄清这行代码的意义,我们搜索一下__AtAutoreleasePool,它的定义是这样的:
struct __AtAutoreleasePool {
__AtAutoreleasePool() {
atautoreleasepoolobj = objc_autoreleasePoolPush();}
~__AtAutoreleasePool() {
objc_autoreleasePoolPop(atautoreleasepoolobj);}
void * atautoreleasepoolobj;
};
这个结构体会在初始化时调用 objc_autoreleasePoolPush()
方法,会在析构时调用 objc_autoreleasePoolPop
方法。
这表明,我们的 main
函数在实际工作时其实是这样的:
int main(int argc, const char * argv[]) {
{
void * atautoreleasepoolobj = objc_autoreleasePoolPush();
// do whatever you want
objc_autoreleasePoolPop(atautoreleasepoolobj)<