简体   繁体   English

在没有 Objective-C 的情况下使用 Apple 自动释放池

[英]Using Apple autorelease pools without Objective-C

I am developing an application that needs to work on Linux, Windows and Mac OS X. To that purpose, I am using C++ with Qt.我正在开发一个需要在 Linux、Windows 和 Mac OS X 上运行的应用程序。为此,我将 C++ 与 Qt 一起使用。

For many reasons, on Mac OS X, I need to use CoreFoundation functions (such as CFBundleCopyBundleURL ) that creates core objects that need to be released with CFRelease .出于多种原因,在 Mac OS X 上,我需要使用 CoreFoundation 函数(例如CFBundleCopyBundleURL )来创建需要使用CFRelease发布的核心对象。 But doing so generate a lots of these warnings:但是这样做会产生很多这样的警告:

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

All the code I've seen concerning these autorelease pools are written in Objective-C.我看到的所有关于这些自动释放池的代码都是用 Objective-C 编写的。 Does anybody know how to create/use autorelease pools in C or C++?有人知道如何在 C 或 C++ 中创建/使用自动释放池吗?

All the code I've seen concerning these autorelease pools are written in Objective-C.我看到的所有关于这些自动释放池的代码都是用 Objective-C 编写的。

Because autorelease pools only exist in Cocoa and Cocoa Touch.因为自动释放池只存在于 Cocoa 和 Cocoa Touch 中。

Does anybody know how to create/use autorelease pools in C or C++?有人知道如何在 C 或 C++ 中创建/使用自动释放池吗?

The only way to do it is to wrap Cocoa code (the creation and drainage of a pool) in a pair of C functions.唯一的方法是将 Cocoa 代码(池的创建和排放)包装在一对 C 函数中。 Even then, that is an ugly hack that merely masks a deeper problem.即便如此,这是一个丑陋的黑客攻击,只是掩盖了一个更深层次的问题。

What you really should do is find out exactly what is autoreleasing objects (Instruments will help you do this) and either fix it or excise it.你真正应该做的是准确地找出什么是自动释放对象(仪器将帮助你做到这一点)并修复它或切除它。

id is a C declaration. id是一个 C 声明。 You can simply add scope based autorelease pools to your cpp program like so:您可以像这样简单地将基于范围的自动释放池添加到您的 cpp 程序中:

autorelease_pool.hpp自动释放池.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自动释放池.mm

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

In a cpp program:在 cpp 程序中:

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

An alternative (which can be very easy to use incorrectly) is to use the ObjC runtime directly - which would look like the following C program:另一种选择(可能很容易错误地使用)是直接使用 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"));

The error you get is caused by something somewhere creating an Objective-C class (NSURL) using the convenience static method [NSURL urlWithString:].您得到的错误是由某处使用便利静态方法 [NSURL urlWithString:] 创建一个 Objective-C 类 (NSURL) 引起的。 Methods that return objects that aren't "alloc" or "copy" should put the object inside an autorelease pool before returning the object.返回非“分配”或“复制”对象的方法应在返回对象之前将对象放入自动释放池中。 And since you haven't setup one up it'll just crash or leak memory.而且由于您还没有设置它,它只会崩溃或泄漏内存。

I'm not sure exactly how to fix this but you need to put something like:我不确定如何解决此问题,但您需要输入以下内容:

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

somewhere in your code.在您的代码中的某处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM