NSAutorelease 内存泄漏

发布于 2024-08-08 05:42:51 字数 187 浏览 8 评论 0原文

我在控制台中收到此错误消息:

*** _NSAutoreleaseNoPool(): Object 0x10d2e0 of class NSPathStore2
    autoreleased with no pool in place - just leaking

我无法弄清楚错误是什么?

谢谢。

I am getting this error message in the console:

*** _NSAutoreleaseNoPool(): Object 0x10d2e0 of class NSPathStore2
    autoreleased with no pool in place - just leaking

I can't figure out what is the error?

Thanks.

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

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

发布评论

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

评论(3

抚笙 2024-08-15 05:42:51

这是一个典型的内存管理问题,您在没有自动释放池的情况下自动释放了一些对象。自动释放并不是魔法。有一个 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];
}

现在您只需弄清楚在另一个线程中运行代码的位置即可。

This is a classic memory management issue, you are autoreleasing some objects without having an autorelease pool in place. Autoreleasing is not a magic. There is an object of type NSAutoreleasePool that keeps track of all objects you autorelease and ‘from time to time’ releases them:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// An autoreleased object referenced by our pool.
id object = [NSNumber numberWithInt:1]; 
[pool drain];
// Our object no longer valid.

Each thread has to have its own autorelease pool. That’s quite logical, because threads run ‘at the same time’ and if they shared a common autoreleased pool, it could release an object while you are still working with it.

Now the point. There is a default autorelease pool in the main thread of every application, which means you don’t have to think about all of this and autoreleased objects are collected just fine. But if you create another thread, you are usually forced to also create an autorelease pool for this thread. Otherwise there is nobody to claim the autoreleased objects and they just leak. Which is exactly why you are getting the warning.

Leaking thread without an autorelease pool can look like this:

- (void) doSomethingInBackground
{
    id object = [NSNumber numberWithInt:1];
}

- (void) someOtherMethod
{
    [self performSelectorInBackground:@selector(doSomethingInBackground);
}

The fix is simple:

- (void) doSomethingInBackground
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    id object = [NSNumber numberWithInt:1];
    [pool drain];
}

Now you only have to figure out where you are running code in another thread.

_蜘蛛 2024-08-15 05:42:51

听起来您已经在新线程上生成了一个方法(可能使用 + (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument;)

的任何方法在自己的线程上运行需要设置一个自动释放池来捕获任何自动释放的对象:

- (void)myLovelyThreadedMethod
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    ... // your code here

    [pool release];
}

It sounds like you've spawned a method onto a new thread (possibly using + (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument;)

Any method that runs on its own thread will need to have an autorelease pool setup up to catch any autoreleased objects:

- (void)myLovelyThreadedMethod
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    ... // your code here

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