NSAutorelease内存泄漏

时间:2009-10-21 09:43:36

标签: cocoa memory-leaks nsautoreleasepool

我在控制台中收到此错误消息:

*** _NSAutoreleaseNoPool(): Object 0x10d2e0 of class NSPathStore2
    autoreleased with no pool in place - just leaking

我无法弄清楚错误是什么?

感谢。

3 个答案:

答案 0 :(得分:12)

这是一个典型的内存管理问题,您在没有自动释放池的情况下自动释放某些对象。自动释放不是一种魔力。有一个NSAutoreleasePool类型的对象可以跟踪您自动发布的所有对象,并且“不时”释放它们:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// An autoreleased object referenced by our pool.
id object = [NSNumber numberWithInt:1]; 
[pool drain];
// Our object no longer valid.

每个线程都必须拥有自己的自动释放池。这是非常合乎逻辑的,因为线程“同时”运行,如果它们共享一个共同的自动释放池,它可能会在您使用它时释放一个对象。

现在重点。每个应用程序的主线程中都有一个默认的自动释放池,这意味着您不必考虑所有这些,并且可以很好地收集自动释放的对象。但是如果你创建另一个线程,你通常也会被迫为这个线程创建一个自动释放池。否则,没有人可以声称自动释放的对象,他们只是泄漏。这就是你收到警告的原因。

没有自动释放池的泄漏线程可能如下所示:

- (void) doSomethingInBackground
{
    id object = [NSNumber numberWithInt:1];
}

- (void) someOtherMethod
{
    [self performSelectorInBackground:@selector(doSomethingInBackground);
}

修复很简单:

- (void) doSomethingInBackground
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    id object = [NSNumber numberWithInt:1];
    [pool drain];
}

现在你只需要弄清楚你在另一个线程中运行代码的位置。

答案 1 :(得分:2)

听起来你已经在一个新线程上产生了一个方法(可能使用+ (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument;

任何在自己的线程上运行的方法都需要设置一个自动释放池来捕获任何自动释放的对象:

- (void)myLovelyThreadedMethod
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    ... // your code here

    [pool release];
}

答案 2 :(得分:1)

尝试使用Clang Static Analyzer