Autorelease机制是iOS开发者管理对象内存的好伙伴,MRC中,调用[obj autorelease] 来延迟内存的释放。这里我们通过一个例子,来阐述autorelease到底什么时候释放。
例:
1.新建一个Mac工程。
2.在终端cd到改工程目录main.m文件夹下。
3.执行clang -rewrite-objc main.m
命令,改目录下会多一个main.cpp的文件。
4.打开main.cpp文件,main函数编译后如下图所示:
OC中的代码
Person *person = [[[Person alloc]init]autorelease];
编译后的代码
/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;
Person *person = ((Person *(*)(id, SEL))(void *)objc_msgSend)((id)((Person *(*)(id, SEL))(void *)objc_msgSend)((id)((Person *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("Person"), sel_registerName("alloc")), sel_registerName("init")), sel_registerName("autorelease"));
在这段代码中,我们可以醒目的看到/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;
,点击查看,我们发现__AtAutoreleasePool
是一个结构体。结构体代码如下:
struct __AtAutoreleasePool {
// 构造函数,在创建结构体的时候调用
__AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}
// 析构函数,在结构体销毁的时候调用
~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}
void * atautoreleasepoolobj;
};
【小结】
① 执行__AtAutoreleasePool __autoreleasepool;
② 调用__AtAutoreleasePool
构造函数;即会调用 objc_autoreleasePoolPush()
方法;
③ 执行完Person *person = [[[Person alloc]init]autorelease];
函数之后,括号内函数执行完了,即将调用objc_autoreleasePoolPop
函数。
所以Person *person = [[[Person alloc]init]autorelease];
代码的本质是:
大括号前调用
atautoreleasepoolobj = objc_autoreleasePoolPush();;
大括号后调用
objc_autoreleasePoolPop(atautoreleasepoolobj);
伪代码 如下:
int main(int argc, const char * argv[]) {
@autoreleasepool {
atautoreleasepoolobj = objc_autoreleasePoolPush();
Person *person = [[[Person alloc]init]autorelease];
objc_autoreleasePoolPop(atautoreleasepoolobj);
}
return 0;
}
网友评论