2009-10-21 96 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]; 
}