Question

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.

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. 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. Does anybody know how to create/use autorelease pools in C or C++?

Was it helpful?

Solution

id is a C declaration. You can simply add scope based autorelease pools to your cpp program like so:

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]; }

In a cpp program:

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:

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

OTHER TIPS

All the code I've seen concerning these autorelease pools are written in Objective-C.

Because autorelease pools only exist in Cocoa and Cocoa Touch.

Does anybody know how to create/use autorelease pools in C or 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. 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.

The error you get is caused by something somewhere creating an Objective-C class (NSURL) using the convenience static method [NSURL urlWithString:]. 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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top