0%

Objective-C内存管理之Autorelease

顾名思义, autorelease就是自动释放, 类似于C语言中的局部变量, 当超出其作用域时, 该局部变量会被自动废弃.

autorelease的具体使用方法如下:

  1. 生成并持有NSAutoreleasePool对象
  2. 调用已分配对象的autorelease实例方法
  3. 废弃NSAutoreleasePool对象

NSAutoreleasePool对象的生存周期相当于C语言变量的作用域. 对于所有调用过autorelease实例方法的对象, 在废弃NSAutoreleasePool对象的同时, 都将调用release实例方法.

用源代码表示如下:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
id obj = [[NSObject alloc]init];
[obj autorelease];
[pool drain];	//等同于[obj release]
    

在Cocoa框架中, 程序主循环的NSRunLoop会自动对NSAutoreleasePool对象进行生成, 持有和废弃. 尽管如此, 但在大量生成 autorelease对象时, 只要不废弃NSAutoreleasePool对象, 那么其中生成的对象就不会被释放, 因此可能会产生内存不足的情况. 典型的例子是处理大量图像时, 图像文件读入到NSData对象, 并从中生成UIImage对象, 进行处理后生成新的UIImage对象. 这种情况下, 会产生大量autorelease的对象.

for (int i = 0; i < 图像数量; i++) {
    /* 
     * 读入图像
     * 大量产生autorelease的对象
     * 由于始终没有废弃NSAutoreleasePool对象
     * 最终导致内存不足
     */
}

此时,需要在适当的地方生成,持有或废弃NSAutoreleasePool对象.

for (int i = 0; i < 图像数量; i++) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
    /*
     * 读入图像
     * 大量产生autorelease的对象
     */
    
    [pool drain];
    
    /*
     * 通过废弃pool对象
     * autorelease的对象被一起release
     */
}

另外, Cocoa框架中也有很多类方法用于返回autorelease的对象, 比如:

    id array = [NSMutableArray arrayWithCapacity:1];
    

等同于:

id array = [[[NSMutableArray alloc]initWithCapacity:1] autorelease];