3

我正在开发一个需要在 Linux、Windows 和 Mac OS X 上运行的应用程序。为此,我将 C++ 与 Qt 一起使用。

出于多种原因,在 Mac OS X 上,我需要使用 CoreFoundation 函数(例如CFBundleCopyBundleURL)来创建需要使用CFRelease. 但是这样做会产生很多这样的警告:

*** __NSAutoreleaseNoPool(): Object 0x224f7e0 of class NSURL autoreleased with no pool in place - just leaking

我看到的所有关于这些自动释放池的代码都是用 Objective-C 编写的。有人知道如何在 C 或 C++ 中创建/使用自动释放池吗?

4

4 回答 4

2

http://www.codeproject.com/KB/cpp/memreleasepool.aspx

于 2010-11-04T16:08:29.130 回答
1

我看到的所有关于这些自动释放池的代码都是用 Objective-C 编写的。

因为自动释放池只存在于 Cocoa 和 Cocoa Touch 中。

有人知道如何在 C 或 C++ 中创建/使用自动释放池吗?

唯一的方法是将 Cocoa 代码(池的创建和排放)包装在一对 C 函数中。即便如此,这是一个丑陋的黑客攻击,只是掩盖了一个更深层次的问题。

你真正应该做的是准确地找出什么是自动释放对象(仪器将帮助你做到这一点)并修复它或切除它。

于 2010-04-01T08:13:45.987 回答
1

id是一个 C 声明。您可以像这样简单地将基于范围的自动释放池添加到您的 cpp 程序中:

自动释放池.hpp

class t_autorelease_pool {
public:
    t_autorelease_pool();
    ~t_autorelease_pool();
private:
    id d_pool; // << you may opt to preprocess this out on other platforms.
private:
    t_autorelease_pool(const t_autorelease_pool&);
    t_autorelease_pool& operator=(const t_autorelease_pool&);
};

自动释放池.mm

t_autorelease_pool::t_autorelease_pool() : d_pool([NSAutoreleasePool new]) {}
t_autorelease_pool::~t_autorelease_pool() { [this->d_pool drain]; }

在 cpp 程序中:

void UpdateUI() {
    t_autorelease_pool pool;
    // your/their autoreleasing code here
}

另一种选择(可能很容易错误地使用)是直接使用 ObjC 运行时 - 它看起来像以下 C 程序:

#include <objc/runtime.h>
#include <objc/message.h>
...
id pool = objc_msgSend(objc_getClass("NSAutoreleasePool"), sel_getUid("new")); 
/* do stuff */
objc_msgSend(pool, sel_getUid("drain"));
于 2011-11-11T14:39:21.967 回答
0

您得到的错误是由某处使用便利静态方法 [NSURL urlWithString:] 创建一个 Objective-C 类 (NSURL) 引起的。返回非“分配”或“复制”对象的方法应在返回对象之前将对象放入自动释放池中。而且由于您还没有设置它,它只会崩溃或泄漏内存。

我不确定如何解决此问题,但您需要输入以下内容:

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
doStuff();
[pool release];

在您的代码中的某处。

于 2010-10-21T03:00:30.897 回答