自动释放溺水

时间:2010-08-14 22:15:28

标签: objective-c cocoa cocoa-touch memory-management memory-leaks

我遇到了一个似乎在自动释放池中被称为“溺水”的问题。

我的代码正确创建和销毁对象。但是,我使用了一些类方法,在我不知道的情况下自动释放几个变量。考虑到它们每分钟循环成千上万次......我发现自己淹没在程序中某处遗失的数千个未发布的物体中。

2个问题:

  1. 所以要么我不使用AT ALL的类方法 - 这是一个永久的解决方案,或者,即便如此,某些实例方法(Foundation,UIKit)仍然会在不知情的情况下自动释放对象吗?

  2. 或者我可以在调用类方法之前分配一个自动释放池,并在调用类方法之后将其耗尽 - 这是一个永久的解决方案吗?

2 个答案:

答案 0 :(得分:2)

  1. 仅仅因为你不使用类方法并不意味着你要避免使用自动释放的对象。例如:NSString * path = [anotherString stringByAppendingPathComponent:@"foo"]返回一个自动释放的对象,但不涉及任何类方法。据我所知,避免自动释放对象的唯一方法是不使用对象。如果确实想要走这条路线,请查看CoreFoundation。 (我不建议走那条路。)

  2. 如果您确实有一些疯狂的工厂方法可以创建大量的自动释放池,那么我可能会这样做:

    + (id) crazyFactoryMethodWithFoo:(id)foo {
      NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
      id returnValue = nil;
      //generate gobs of autoreleased objects
      returnValue = [something retain];
      [pool release];
      return [returnValue autorelease];
    }

    通过在排空池之前显式保留返回值,可以确保返回值超出自动释放池的销毁范围。然后通过自动释放返回值并返回它来平衡retain

答案 1 :(得分:2)

Dave DeLong已经回答了你的问题,但通常只有当你把游泳池填得太高时才是你的问题。在这种情况下,只需为循环的每次迭代创建另一个自动释放池。

for (NSUInteger i = 0; i < 1000000000; i++)
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    // do the work

    [pool release];
}

对象会自动添加到当前线程的最近创建的自动释放池中。通过为循环的每次迭代创建一个,您可以快速摆脱不需要的对象,而不是让它们堆积在运行循环池中。