diff options
author | Tor Arne Vestbø <tor.arne.vestbo@digia.com> | 2013-09-03 14:49:09 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-11 21:50:46 +0200 |
commit | fc2b36ca1def7301c4af8b3ad2dca2f5a1b0a568 (patch) | |
tree | b0904c76a415783fb6414ea89d6e637eb34c9ffd /src/plugins/platforms | |
parent | ba7da9b733f2c5fc75ddbf73e2615bee1663c5b4 (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')
-rw-r--r-- | src/plugins/platforms/ios/qiosapplicationstate.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qiosapplicationstate.mm | 24 |
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() |