使用没有Objective-C的Apple自动释放池

时间:2010-04-01 01:09:01

标签: c++ macos cocoa nsautoreleasepool

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

由于许多原因,在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 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

  

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

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

  

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

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

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

答案 2 :(得分:1)

id是C声明。您可以简单地将基于范围的自动释放池添加到您的cpp程序中,如下所示:

<强> autorelease_pool.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&);
};

<强> 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"));

答案 3 :(得分:0)

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

我不确定如何解决这个问题,但你需要提出类似的内容:

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

代码中的某处。