2009-10-21 98 views
1

我在控制台收到此错误信息:NSAutorelease内存泄露

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

我想不出有什么错误?

谢谢。

回答

12

这是一个经典的内存管理问题,您正在autoreleasing一些对象,而没有一个autorelease池。 Autoreleasing不是一种魔力。有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

它应该是[池排水]不是[池中版本] ... – 2010-11-05 13:31:24

+0

你是对的(我只在iOS那里是这两个之间没有区别工作)。 – zoul 2010-11-07 14:17:33

+0

为了帮助查找泄漏,请打开gdb中的__NSAutoreleaseNoPool。 – gaspard 2011-02-14 11:17:49

2

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

是在自己的线程中运行需要有一个自动释放池设置了捕捉任何自动释放对象的任何方法:

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

    ... // your code here 

    [pool release]; 
}