为了方便程序员管理内存,苹果在OC中引入了自动释放池(Autorelease Pool)。在遵守一些规则的情况下,可以自动释放对象。但即使有这么一个工具,OC的内存仍需要程序员时刻关注。
原理
Autorelease Pool全名叫做NSAutoreleasePool,是OC中的一个类。autorelease pool并不是天生就有的,你需要手动的去创建它。一般地,在新建一个iphone项目的时候,xcode会自动地为你创建一个Autorelease Pool,这个pool就写在Main函数里面。在NSAutoreleasePool中包含了一个可变数组,用来存储被声明为autorelease的对象。当NSAutoreleasePool自身被销毁的时候,它会遍历这个数组,release数组中的每一个成员(注意,这里只是release,并没有直接销毁对象)。若成员的retain count 大于1,那么对象没有被销毁,造成内存泄露。默认的NSAutoreleasePool 只有一个,你可以在你的程序中创建NSAutoreleasePool,被标记为autorelease的对象会跟最近的NSAutoreleasePool匹配。可以嵌套使用NSAutoreleasePool。
缺点
即使NSAutoreleasePool看起来没有手动release那么繁琐,但是使用NSAutoreleasePool来管理内存的方法还是不推荐的。因为在一个NSAutoreleasePool里面,如果有大量对象被标记为autorelease,在程序运行的时候,内存会剧增,直到NSAutoreleasePool被销毁的时候才会释放。如果其中的对象足够的多,在运行过程中你可能会收到系统的低内存警告,或者直接crash。
扩展
如果你极具好奇心,把Main函数中的NSAutoreleasePool代码删除掉,然后再自己的代码中把对象声明为autorelease,你会发现系统并不会给你发出错误信息或者警告。用内存检测工具去检测内存的话,你可能会惊奇的发现你的对象仍然被销毁了。其实在新生成一个Run Loop的时候,系统会自动的创建一个NSAutoreleasePool,该NSAutoreleasePool无法被删除。
实例
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
ClassA *a=[[[ClassA alloc] init] autorelease];
ClassB *b=[[[ClassB alloc] init] autorelease];
ClassC *c=[[[ClassC alloc] init] autorelease];
[pool release];