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

时间:2011-07-06 04:37:32

标签: objective-c cocoa memory-management

NSAutoreleasePool ..应该只有一个吗?为什么你想拥有一个以上?您是否希望将多个池作为单个类的一部分?

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

对不起20个问题,请帮助我更好地理解

1 个答案:

答案 0 :(得分:12)

  

NSAutoreleasePool ..应该有   只有一个?

不,不一定。您可以根据需要创建任意数量的自动释放池。

  

为什么你想拥有更多呢?   一?你想要更多吗?   而不是一个池作为单个池的一部分   类?

这个想法是让你的记忆“尽可能低”。使用自动释放是一种作弊,推迟释放你的对象直到“以后”。有时你知道什么时候“以后” - 在这些情况下,制作你自己的自动释放池可能很聪明。

这是什么意思?好吧,想象你有以下循环:

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

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

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

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

  

如果您有多个池,哪一个   将包含被要求的对象   是[autorelease] d?

最近一次。

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

正如BJ Homer指出的那样,上面段落中的堆栈实际上并不是真正的全局 - 每个线程实际上有一个堆栈。但我无法弄清楚如何重写上面的段落,并通过使用“线程本地”之类的术语让它易于理解......所以...这个附录必须足够:)