当您向一个对象发送一个autorelease消息时,cocoa就会将这个对象的一个引用放入到最新的自动释放池。当程序执行结束时,自动释放池就会被释放,池中所有的对象也就会被释放,也就是执行一次release操作。所以说,自动释放池是OC中的一种内存自动回收机制,可以将一些临时变量通过自动释放池来统一回收和释放。
在一个OC编写的iOS项目中,main.m文件下的代码如下:这里就使用到了自动释放池。
int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }
@autoreleasepool { .... }就如同上述main.m中的一样。一定要记住,如果一个对象使用了alloc来进行创建,那么一定要用release或者autorelease来进行释放。
现在我们来看一下,对象应该在什么时候释放?在运行时,当一个对象没有被任何一个对象引用时,在某一个合适的时间点被释放,程序是无法捕捉到是什么时候释放的。程序可以有多个自动释放池,自动释放池也可以相互嵌套。
我们来看一个为什么要使用自动释放池的例子:
for (int i = 0; i < 1000000; i++) { NSString *string = [NSString stringWithString:@"ABC"]; NSLog(@"%@",string); }
如果在程序中产生大量的临时对象,这时就需要考虑使用自动释放池了。这样一直循环下去,就会造成内存泄露的问题(内存泄露是指不再使用的内存没有进行释放,导致我们不能对这块内存再次使用。),这些临时对象会不断累积分配内存,直到整个循环结束。我们需要做的就是每循环一次,就释放一次内存。代码修改如下:
for (int i = 0; i < 1000000; i++) { @autoreleasepool { NSString *string = [NSString stringWithString:@"ABC"]; NSLog(@"%@",string); } }
最后我们来谈谈自动释放池的数据结构。自动释放池是一个栈的结构,当创建一个新的自动释放池时,会被放到栈顶。接到autorelease消息的对象会被放到这个自动释放池中。
github主页:https://github.com/chenyufeng1991 。欢迎大家访问!