summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/ios
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@digia.com>2013-09-03 14:49:09 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-11 21:50:46 +0200
commitfc2b36ca1def7301c4af8b3ad2dca2f5a1b0a568 (patch)
treeb0904c76a415783fb6414ea89d6e637eb34c9ffd /src/plugins/platforms/ios
parentba7da9b733f2c5fc75ddbf73e2615bee1663c5b4 (diff)
iOS: Guard against this and self being deleted when using dispatch_async
When the QIOSApplicationState object owned by the platform integration was deleted we would deallocate QIOSApplicationStateListener, but would then get a callback on the main queue later on where we would reference the now invalid 'this' variable. By moving the dispatch_async call to QIOSApplicationStateListener and using 'self' we ensure that the listener is retained for as long as the block is valid. This opens us up for receiving application state callbacks after QCoreApplication has been deleted, so we need to guard against that. Change-Id: I2ac14d28d72fd79764e12b6657234b54d846cb79 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@digia.com>
Diffstat (limited to 'src/plugins/platforms/ios')
-rw-r--r--src/plugins/platforms/ios/qiosapplicationstate.h2
-rw-r--r--src/plugins/platforms/ios/qiosapplicationstate.mm24
2 files changed, 18 insertions, 8 deletions
diff --git a/src/plugins/platforms/ios/qiosapplicationstate.h b/src/plugins/platforms/ios/qiosapplicationstate.h
index e726ad895e..57ea547e72 100644
--- a/src/plugins/platforms/ios/qiosapplicationstate.h
+++ b/src/plugins/platforms/ios/qiosapplicationstate.h
@@ -42,6 +42,8 @@
#ifndef QIOSAPPLICATIONSTATE_H
#define QIOSAPPLICATIONSTATE_H
+#include <QtCore/qglobal.h>
+
QT_BEGIN_NAMESPACE
@class QIOSApplicationStateListener;
diff --git a/src/plugins/platforms/ios/qiosapplicationstate.mm b/src/plugins/platforms/ios/qiosapplicationstate.mm
index df64edf465..8d77e608e5 100644
--- a/src/plugins/platforms/ios/qiosapplicationstate.mm
+++ b/src/plugins/platforms/ios/qiosapplicationstate.mm
@@ -39,10 +39,12 @@
**
****************************************************************************/
-#import <UIKit/UIKit.h>
+#include "qiosapplicationstate.h"
#include <qpa/qwindowsysteminterface.h>
-#include "qiosapplicationstate.h"
+#include <QtCore/qcoreapplication.h>
+
+#import <UIKit/UIKit.h>
@interface QIOSApplicationStateListener : NSObject
@end
@@ -71,6 +73,12 @@
selector:@selector(applicationDidEnterBackground)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
+
+ // Update the current state now, since we have missed all the updates
+ // posted from AppKit so far. But let QPA finish initialization first.
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self handleApplicationStateChanged:[UIApplication sharedApplication].applicationState];
+ });
}
return self;
}
@@ -112,6 +120,12 @@
- (void) handleApplicationStateChanged:(UIApplicationState) uiApplicationState
{
+ // We may receive application state changes after QCoreApplication has
+ // gone down, as the block we schedule on the main queue keeps the
+ // listener alive. In that case we just ignore the notification.
+ if (!qApp)
+ return;
+
Qt::ApplicationState state;
switch (uiApplicationState) {
case UIApplicationStateActive:
@@ -145,12 +159,6 @@ QT_BEGIN_NAMESPACE
QIOSApplicationState::QIOSApplicationState()
: m_listener([[QIOSApplicationStateListener alloc] init])
{
- // Update the current state now, since we have missed all the updates
- // posted from AppKit so far. But let QPA finish initialization first:
- dispatch_async(dispatch_get_main_queue(), ^{
- UIApplicationState state = [UIApplication sharedApplication].applicationState;
- [m_listener handleApplicationStateChanged:state];
- });
}
QIOSApplicationState::~QIOSApplicationState()