【问题标题】:NSAutoreleasePool in loopsNSAutoreleasePool 循环
【发布时间】:2012-04-20 10:13:22
【问题描述】:

假设我有这样的代码:

NSAutoreleasePool* pool=[[NSAutoreleasePool alloc]init];
for(unsigned int i=0;i<10;i++)
{
    NSDate* date=[[NSDate alloc]init];
}
[pool drain];

请注意,此代码仅用于显示我可以做什么,它是对我通常做的事情的简化。 因此,在每次迭代中,都会分配并初始化一个新的 NSDate。 NSAutoreleasePool 是否将它们全部耗尽,或者我必须以这种方式在循环中添加 NSAutoreleasePool:

for(unsigned int i=0;i<10;i++)
{
    NSAutoreleasePool* pool=[[NSAutoreleasePool alloc]init];
    NSDate* date=[[NSDate alloc]init];
    [pool drain];
}

?
另外,我的书(mac os x 的可可编程)没有提到 NSAutoreleasePool,它只是这样使用它:

@autoreleasepool
{
    <code>
}

我已经读到这种方式比使用 NSAutoreleasePool 更有效,但是如果我使用它,我会收到语法错误:
“程序中出现意外的 '@'”
为什么会这样?

我试过这样修改代码:

NSAutoreleasePool* pool=[[NSAutoreleasePool alloc]init];
for(unsigned int i=0;i<10;i++)
{
    NSDate* date=[[NSDate alloc]init];
    [date autorelease];
}
[pool drain];

正确吗?我认为保留了 10 个不同的对象(计数为 1),然后添加到自动释放池中。 我没有内存泄漏吗?有没有办法用 gdb 检查这个对象数?

【问题讨论】:

    标签: objective-c nsautoreleasepool


    【解决方案1】:

    当你分配/初始化一个类时,返回的实例一般不会被自动释放。所以,不,在那个示例中,根本不需要自动释放池。

    一般来说,当您有可量化的性能问题表明需要自动释放池时,您应该只在代码中添加自动释放池。不要解决你没有的问题。

    如果@autoreleasepool 不起作用,那是因为您使用的是旧编译器。

    【讨论】:

    • NSDate 实例本身不会自动释放,但不知道在这两种方法中与其他对象在内部完成了哪些工作。他们可能有自动发布的东西。也就是说,我同意该特定示例对于手动管理自动释放池似乎并不成熟,但 Ramy 确实说这是一个仅用于说明的玩具示例。一般来说,自动释放池在耗尽之前没有任何帮助。所以,如果你想防止循环堆积物体,你必须在循环中放一个排水管。此外,@Ramy 在这两种情况下都泄露了 NSDate。
    • 这是一个泄漏,因为他使用 alloc+init 但从未释放或自动释放它。
    • 是的——我应该知道最好不要在喝咖啡之前评论 SO。 Herp de derp,“打开 ARC,伙计,因为编译器比你聪明。”
    • 是的,我将在 Mac os X 10.7 上打开 ARC;但是我想知道释放/保留系统是如何工作的。我尝试过修改代码。你认为它是正确的(没有泄漏)吗?
    • 该代码不会泄漏,但是没有理由使用 -autorelease 代替 -release。
    【解决方案2】:

    来自苹果docs

    If you write a loop that creates many temporary objects.
    You may use an autorelease pool block inside the loop to dispose of those objects before the next iteration. Using an autorelease pool block in the loop helps to reduce the maximum memory footprint of the application.
    

    如果@Ramy 使用不是更好:

    for(unsigned int i=0;i<10;i++)
    {
        NSAutoreleasePool* pool=[[NSAutoreleasePool alloc]init];
        NSDate* date=[[NSDate alloc]init];
        [date autorelease];
        [pool drain];
    }
    

    【讨论】:

      猜你喜欢
      • 2011-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-01
      • 2011-11-09
      相关资源
      最近更新 更多