3

因此,我正在使用 [NSThread detachNewThreadSelector] 来生成一个新线程,并且在控制台中出现“autoreleased with no pool in place”错误。我知道如果您未能创建自动释放池,就会发生这种情况,但问题是,我正在创建一个。我在同一个应用程序的其他部分使用了类似的代码,并且没有收到这些错误。

以下是相关代码:

- (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 对象,并且所有这些对象也会被报告。

将不胜感激任何可能有帮助的提示或指示!

谢谢!

4

3 回答 3

5

当您创建一个新线程时,您还需要为其创建一个新的自动释放池。在您的情况下,这看起来就像添加一样简单:

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

在开头loadImageFromURL:

[pool drain];

在末尾。

您可能不需要或不想要您在startThread:. 查看线程编程指南,尤其是“编写线程条目例程”部分。

于 2011-01-24T18:30:10.133 回答
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 建议的那样,您应该在使用完自动更新池时使用drain而不是使用。release

于 2011-01-24T18:34:26.280 回答
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   
    }
}
于 2012-10-29T06:43:19.343 回答