2011-01-24 28 views
3

因此,我正在使用[NSThread detachNewThreadSelector]產生一個新線程,並在控制檯中得到「無地方自動釋放」錯誤。我知道如果您未能創建自動發佈池,可能會發生這種情況,但事實是,我正在創建一個。我在同一個應用程序的其他部分使用類似的代碼,不會得到這些錯誤。iOS自動釋放,沒有池 - 但我創建ARP!

下面是相關代碼:

- (void) startThread:(NSString*)strURL 
{ 
    // start new thread to load image 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    [NSThread detachNewThreadSelector:@selector(loadImageFromURL:) toTarget:self withObject:strURL]; 
    [pool release]; 
} 

- (void) loadImageFromURL:(NSString*)strURL 
{ 
    NSNumber* nn = [NSNumber numberWithInt:self.tag]; 
    NSLog(@"loadURL: Tag number == %i", [nn intValue]); 

    // other code here actually does the work 
} 

現在,在loadImageFromURL更多的代碼實際上做的工作(加載從遠程服務器的圖像) - 但問題表現沒有代碼,所以我刪除了它(只是所以你不認爲我有一個毫無意義的線程,它什麼都不做!)。我只留下了一行代碼,它演示了這個問題 - 它創建了一個自動發佈的NSNumber對象。

運行此代碼時,它報告給控制檯:

__NSAutoreleaseNoPool(): Object 0x535c0e0 of class NSCFNumber autoreleased with no pool in place - just leaking

當然,真正的代碼創造了許多其他的AR對象,他們都得到報告爲好。

將不勝感激的任何提示或指針可能會有所幫助!

謝謝!

回答

5

當你創建一個新線程時,你還需要爲它創建一個新的自動釋放池。在你的情況,看起來那麼簡單,並補充說:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

loadImageFromURL:開始和

[pool drain]; 

末。

您可能不需要或想要在startThread:中創建的游泳池。查看Threading Programming Guide,特別是「編寫你的線程入口例程」部分。

+0

卡爾 - 我爲浪費你的時間表示歉意。你當然是對的。 * IS *我在使用detachNewThreadSelector的應用程序的其他部分如何做。只是看不到樹林。我被固定在錯誤的模式上,從來沒有看過我的其他代碼,我確信它是一樣的。謝謝你快速的回覆! – Jordan 2011-01-24 18:38:56

4

在您的代碼上,- (void) startThread:(NSString*)strURL正在主線程中運行,而- (void) loadImageFromURL:(NSString*)strURL正在您要分離的後臺線程上運行。

主線程已有NSAutoreleasePool,因此您在startThread:中創建的那個可能不需要。但是,後臺線程不會創建NSAutoreleasePool,因此您需要自己創建它。

在你的代碼,這將是這樣的:

- (void) startThread:(NSString*)strURL 
{ 
    // start new thread to load image 
    [NSThread detachNewThreadSelector:@selector(loadImageFromURL:) toTarget:self withObject:strURL]; 
} 

- (void) loadImageFromURL:(NSString*)strURL 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    NSNumber* nn = [NSNumber numberWithInt:self.tag]; 
    NSLog(@"loadURL: Tag number == %i", [nn intValue]); 

    // other code here actually does the work 

    [pool drain]; 
} 

此外,作爲@Carl Norum時建議,那麼當您使用autorelelase池進行使用drain代替release

+0

使用流失與釋放的WRT - 我的所有閱讀都表明(在iOS上)他們是平等的。我可以在它們之間找到的唯一區別是,漏洞爲GC子系統提供了一些提示,這在iOS上不存在。還有其他原因嗎? – Jordan 2011-01-24 19:02:50

1

解決類似問題但使用ARC。

如果使用ARC,您可能會收到錯誤「'NSAutoreleasePool'不可用:不適用於自動引用計數模式」。

用途:

- (void) startThread:(NSString*)strURL 
{ 
    // start new thread to load image 
    [NSThread detachNewThreadSelector:@selector(loadImageFromURL:) toTarget:self withObject:strURL]; 
} 

- (void) loadImageFromURL:(NSString*)strURL 
{ 
    @autoreleasepool {   
     NSNumber* nn = [NSNumber numberWithInt:self.tag]; 
     NSLog(@"loadURL: Tag number == %i", [nn intValue]); 

     // other code here actually does the work 
    } 
}