iOS 自动发布,没有池 - 但我正在创建 ARP!

发布于 2024-10-14 04:38:20 字数 1094 浏览 9 评论 0原文

因此,我使用 [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 对象,并且所有其中一些也被举报。

如果有任何可能有帮助的提示或指示,我们将不胜感激!

谢谢!

So, I am using [NSThread detachNewThreadSelector] to spawn a new thread and I am getting "autoreleased with no pool in place " errors in the console. I know this can happen if you fail to create an auto release pool, but the thing is, I am creating one. I use similar code in other parts of the same app and do NOT get these errors.

Here is the relevant code:

- (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
}

Now, there was more code in loadImageFromURL which actually does the work (of loading an image from a remote server) - but the problem manifests itself without that code, so I've removed it (just so you don't think I have a pointless thread which does nothing!). I left in just one line of code which demonstrates the problem - it creates an autoreleased NSNumber object.

When this code runs, it reports this to the console:

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

Of course, the real code creates many other AR objects and all of them get reported as well.

Would be grateful for any tips or pointers which might help!

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

捎一片雪花 2024-10-21 04:38:20

当你创建一个新线程时,你还需要为其创建一个新的自动释放池。 添加: 一样简单

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

就您而言,这看起来就像在 loadImageFromURL: 的开头和

[pool drain];

结尾处

。您可能不需要或不想要在 startThread: 中创建的池。查看 线程编程指南,特别是“编写线程入口例程”部分。

When you create a new thread, you need to also create a new autorelease pool for it. In your case, that looks as simple as adding:

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

at the beginning of loadImageFromURL: and

[pool drain];

at the end.

You probably don't need or want the pool you're creating in startThread:. Check out the Threading Programming Guide, particularly the "Writing Your Thread Entry Routine" section.

不再见 2024-10-21 04:38:20

在您的代码中, - (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 建议的那样,当您使用完 autorelase 池后,您应该使用 drain 而不是 release

On your code, - (void) startThread:(NSString*)strURL is running in the main thread, while - (void) loadImageFromURL:(NSString*)strURL is running on the background thread you are detaching.

The main thread already has a NSAutoreleasePool, so the one you are creating in startThread: is probably unneeded. However, the background thread will not create a NSAutoreleasePool, so you'd need to create it yourself.

In your code, that would look like:

- (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];
}

Also, as @Carl Norum suggested, you should use drain instead of release when you are done using the autorelelase pool.

呆橘 2024-10-21 04:38:20

类似问题的解决方案,但使用 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   
    }
}

Solution for a similar problem but using ARC.

If using ARC, you could get an error "'NSAutoreleasePool' is unavailable: not available in automatic reference counting mode".

Use:

- (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   
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文