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>
This commit is contained in:
parent
ba7da9b733
commit
fc2b36ca1d
@ -42,6 +42,8 @@
|
||||
#ifndef QIOSAPPLICATIONSTATE_H
|
||||
#define QIOSAPPLICATIONSTATE_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@class QIOSApplicationStateListener;
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user