代码之家  ›  专栏  ›  技术社区  ›  PierreBdR

在不使用Objective-C的情况下使用Apple Autorelease池

  •  3
  • PierreBdR  · 技术社区  · 14 年前

    我正在开发一个应用程序,需要在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
    

    所有关于这些自动存储池的代码都是在Objtovi.C中编写的。有人知道如何在C或C++中创建/使用自动存储池吗?

    4 回复  |  直到 7 年前
        1
  •  1
  •   justin    12 年前

    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"));
    
        3
  •  1
  •   Peter Hosey    14 年前

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

    因为自动租赁池只存在于可可和可可触摸。

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

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

    你真正应该做的是找出什么是自动租赁对象(工具将帮助你做到这一点),并修复或删除它。

        4
  •  0
  •   wm_eddie    14 年前

    您得到的错误是由于某个地方使用便利的静态方法[nsurl urlwithstring:]创建了一个objective-c类(nsurl)。返回非“alloc”或“copy”对象的方法应在返回对象之前将该对象放入自动释放池。既然你还没有设置一个,它只会崩溃或泄漏内存。

    我不确定该如何解决这个问题,但您需要放置如下内容:

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

    在你的代码中。