谁拥有自动释放对象?

Dan*_*ani 2 memory-management objective-c

在objective-c手册中,它写的是类似的东西

return [[[SomeClass alloc] init] autorelease];
Run Code Online (Sandbox Code Playgroud)

可以完成,然后release在任何时候都没有必要,甚至不在接收到该对象的函数中.谁拥有这个对象呢?什么时候发布?

Reg*_*ent 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
}
Run Code Online (Sandbox Code Playgroud)

考虑另一种情况:

- (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
}
Run Code Online (Sandbox Code Playgroud)

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

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];
Run Code Online (Sandbox Code Playgroud)

然而NSAutoreleasePool,高度优化,因此每次迭代一个池通常不是一个问题.


要完全理解NSAutoreleasePools的工作方式,请阅读Mike Ash撰写的这篇优秀文章