diff options
-rw-r--r-- | src/corelib/kernel/qcore_mac_objc.mm | 39 | ||||
-rw-r--r-- | src/corelib/kernel/qcore_mac_p.h | 13 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreapplication_p.h | 8 |
3 files changed, 60 insertions, 0 deletions
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index a91c02f54e..272d6179d1 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -93,6 +93,45 @@ QMacAutoReleasePool::~QMacAutoReleasePool() [static_cast<NSAutoreleasePool*>(pool) drain]; } +#ifdef Q_OS_MACOS +/*! + Ensure that Objective-C objects auto-released in main(), directly or indirectly, + after QCoreApplication construction, are released when the app goes out of scope. + The memory will be reclaimed by the system either way when the process exits, + but by having a root level pool we ensure that the objects get their dealloc + methods called, which is useful for debugging object ownership graphs, etc. +*/ + +QT_END_NAMESPACE +#define ROOT_LEVEL_POOL_MARKER QT_ROOT_LEVEL_POOL__THESE_OBJECTS_WILL_BE_RELEASED_WHEN_QAPP_GOES_OUT_OF_SCOPE +@interface QT_MANGLE_NAMESPACE(ROOT_LEVEL_POOL_MARKER) : NSObject @end +@implementation QT_MANGLE_NAMESPACE(ROOT_LEVEL_POOL_MARKER) @end +QT_NAMESPACE_ALIAS_OBJC_CLASS(ROOT_LEVEL_POOL_MARKER); +QT_BEGIN_NAMESPACE + +const char ROOT_LEVEL_POOL_DISABLE_SWITCH[] = "QT_DISABLE_ROOT_LEVEL_AUTORELEASE_POOL"; + +QMacRootLevelAutoReleasePool::QMacRootLevelAutoReleasePool() +{ + if (qEnvironmentVariableIsSet(ROOT_LEVEL_POOL_DISABLE_SWITCH)) + return; + + pool.reset(new QMacAutoReleasePool); + + [[[ROOT_LEVEL_POOL_MARKER alloc] init] autorelease]; + + if (qstrcmp(qgetenv("OBJC_DEBUG_MISSING_POOLS"), "YES") == 0) { + qDebug("QCoreApplication root level NSAutoreleasePool in place. Break on ~%s and use\n" \ + "'p [NSAutoreleasePool showPools]' to show leaked objects, or set %s", + __FUNCTION__, ROOT_LEVEL_POOL_DISABLE_SWITCH); + } +} + +QMacRootLevelAutoReleasePool::~QMacRootLevelAutoReleasePool() +{ +} +#endif + // ------------------------------------------------------------------------- #ifdef Q_OS_OSX diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h index c2c5a519aa..12e9518979 100644 --- a/src/corelib/kernel/qcore_mac_p.h +++ b/src/corelib/kernel/qcore_mac_p.h @@ -68,6 +68,7 @@ #endif #include "qstring.h" +#include "qscopedpointer.h" #if defined( __OBJC__) && defined(QT_NAMESPACE) #define QT_NAMESPACE_ALIAS_OBJC_CLASS(__KLASS__) @compatibility_alias __KLASS__ QT_MANGLE_NAMESPACE(__KLASS__) @@ -96,6 +97,18 @@ protected: T value; }; + +#ifdef Q_OS_MACOS +class QMacRootLevelAutoReleasePool +{ +public: + QMacRootLevelAutoReleasePool(); + ~QMacRootLevelAutoReleasePool(); +private: + QScopedPointer<QMacAutoReleasePool> pool; +}; +#endif + /* Helper class that automates refernce counting for CFtypes. After constructing the QCFType object, it can be copied like a diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index c646786296..da6ce1249f 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -58,6 +58,10 @@ #include "private/qobject_p.h" #endif +#ifdef Q_OS_MACOS +#include "private/qcore_mac_p.h" +#endif + QT_BEGIN_NAMESPACE typedef QList<QTranslator*> QTranslatorList; @@ -85,6 +89,10 @@ public: QString appName() const; QString appVersion() const; +#ifdef Q_OS_MACOS + QMacRootLevelAutoReleasePool autoReleasePool; +#endif + #ifdef Q_OS_DARWIN static QString infoDictionaryStringProperty(const QString &propertyName); #endif |