谁拥有自动释放对象?

时间:2011-11-16 21:15:32

标签: objective-c memory-management

在objective-c手册中,它写成类似

的内容
return [[[SomeClass alloc] init] autorelease];

可以完成,然后在任何时候都不需要release,即使不是在接收此对象的函数中也是如此。谁拥有这个对象呢?什么时候会被释放?

1 个答案:

答案 0 :(得分:7)

当前的NSAutoreleasePool确实并将在排空时处理释放。

IBAction次调用被包裹在NSAutoreleasePool中,并在通话结束后消失。

对于所有非IBAction调用,将适用以下内容:

说,你有这些方法:

- (id)foo {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    SomeClass *bar = [self bar]; //bar still exists here
    //do other stuff
    //bar still exists here
    //do other stuff
    //bar still exists here
    [pool drain]; //bar gets released right here!
    //bar has been released
}

- (id)bar {
    return [[[SomeClass alloc] init] autorelease]; //bar will still be around after the return
}

考虑另一种情况:

- (void)foo {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    //do other stuff
    [self bar];
    //do other stuff
    [pool drain]; //the string from blee would be released right here;
}

- (void)bar {
    [self baz];
}

- (void)baz {
    NSString *string = [self blee];
}

- (id)blee {
    return [NSString string]; //autoreleased
}

正如您所看到的,甚至不必使用自动释放的字符串对象或返回到创建池的范围。

NSAutoreleasePools存在于堆栈上(每个线程一个),自动释放的对象由调用autorelease时最顶层的池拥有。


更新: 如果你正在处理一个紧凑的循环,并希望保持内存适度低而不减慢你的循环,考虑做这样的事情:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
for (NSUInteger i = 0; i < 1000000000; i++) {
    [NSString stringWithString:@"foo"];
    if (i % 1000 == 0) {
        [pool drain];
        pool = [[NSAutoreleasePool alloc] init];
    }
}
[pool drain];

但是NSAutoreleasePool是高度优化的,因此每次迭代一个池通常不会有太大问题。


要完全了解NSAutoreleasePools如何工作,请阅读此excellent article by Mike Ash