summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qcore_mac_objc.mm39
-rw-r--r--src/corelib/kernel/qcore_mac_p.h13
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h8
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