什么“自动释放没有游泳池”是什么意思?

时间:2011-01-22 15:49:05

标签: multithreading cocoa debugging objective-c++

我的申请结构如下, 核心部分是用C ++编写的,并且大量使用线程,我在Objective C上开发UI, 如果我不执行该线程它工作正常,但我无法禁用,停止线程,UI在我可以看到的日志中随机崩溃,以下消息

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

类似的消息会再出现一次, 通过谷歌搜索来了解,我需要设置NSAutoReleasePool来摆脱它,但它如何可能与C ++代码集成相同。

编辑:核心库将从UI激活,因此我想,可以肯定地说UI在主线程中运行,Lib正在创建/终止线程而不通知UI, 在这种情况下,我可以在UI中调用AutoReleasePool

任何人都可以指导我吗?

2 个答案:

答案 0 :(得分:7)

有关使用Cocoa进行多线程处理的知识,请参阅这些文档:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html

设计你的应用程序是可以的,但是应该记住两件事:

  1. 在主线程上操作像视图(AppKit或UIKit)这样的UI控件时,生命是最简单的(有时是必要的)。您可以在后台线程上使用Foundation对象和一些AppKit / UIKit对象,并且可以从多个线程使用一些Foundation对象。
  2. 如果您在后台线程中使用任何Cocoa对象,则需要在这些线程上设置自动释放池。
  3. 像这样:

    - (void)backgroundThreadStart 
    {
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    
        // do stuff
    
        [pool release];
    }
    

    这将修复您的控制台错误,但您可能还有其他问题导致您看到的实际崩溃。

答案 1 :(得分:1)

这意味着您在没有自动释放池的情况下自动释放了某些内容。

每个线程都有一堆自动释放池。在主线程上,在Cocoa调用代码之前为您创建自动释放池,并在代码返回后耗尽。您自动释放的每个对象(无论是显式还是隐式)都会进入池中,以便池在池耗尽时释放它。创建线程时,您必须自己在该线程上创建并释放自动释放池。 (或者只是不自动释放任何内容,但对于任何有意义的代码量来说,这几乎是不可能的。)

如果你决定在垃圾收集下运行你的代码,你需要在完成后发送池drain,而不是release,因为池是有用。启用GC后,releaseautorelease消息不会执行任何操作 - 它们甚至不会通过。您的自动释放池将通过调用垃圾收集器来响应drain,垃圾收集器与释放池中已存在的对象最接近。

The Memory Management Programming Guide for Cocoa提供了有关自动释放池的更多信息。