我们可以拥有多个NSAutoReleasePools吗?为什么这是必要的?

7

NSAutoreleasePool .. 是否只应该有一个?为什么需要多个?在单个类中是否需要多个池?

如果您有多个池,哪个池将包含被要求进行[autorelease]的对象?有没有办法找出作为池的一部分等待自动释放的对象?

抱歉问了这么多问题,请帮助我更好地理解这个问题。

1个回答

13

NSAutoreleasePool.. 是否只应该有一个?

不一定。您可以根据需要创建任意数量的autorelease池。

为什么要有多个池?您是否曾经想过在单个类的多个部分中拥有多个池?

这样做的想法是尽可能将内存“高水位线”保持低。使用自动释放是一种推迟释放对象的“把戏”,直到“以后”。有时您知道“以后”是什么时候,在这些情况下,最好创建自己的autorelease池。

我的意思是什么?好吧,想象一下您有以下循环:

for (...)
{
     // 1 MB of objects are added to the autorelease pool by some code...
}

1 MB很大!如果该代码循环20次,您将拥有20MB的对象等待释放。更糟糕的是,如果它运行了不确定或无限次数,您的应用程序可能会崩溃。如果您知道该代码是自包含的,则可以通过手动创建自己的autorelease池来强制释放在该块中放入autorelease池的任何内容,如下所示:

for (...)
{
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
     // 1 MB of objects are added to the autorelease pool by some code...
     [pool drain];
}

现在你的“高水位线”只有1MB,而不是20MB或更多!

如果你有多个池,哪一个会包含被要求[自动释放]的对象?

最近的那个。

想象一下有一个全局堆栈。当你初始化一个新的自动释放池时,它将自己添加到这个全局自动释放池的堆栈中。当你在一个对象上调用[xxx autorelease]方法时,自动释放方法会查看位于堆栈顶部的自动释放池,并将自身添加到该自动释放池的对象列表中。当你调用[pool drain]时,该池会循环遍历所有已添加到它的引用,并对它们调用[xxx release]

正如BJ Homer所指出的,上面段落中的堆栈实际上并不是真正的全局性--每个线程实际上都有一个堆栈。但我无法想出如何重写上面的段落并使用像“线程本地”这样的术语使其易于理解...所以...这个补充说明就足够了 :)


1
好的,实际上它是一个线程本地栈,而不是全局栈。但除此之外写得很好。 - BJ Homer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接