2011-01-24 51 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 
    } 
} 
相关问题