Search code examples
c++macoscocoansautoreleasepool

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.

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


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