iOS: cleanup connection when a screen disconnects

The iOS port creates one QIOSViewController per connected
screen. And each view controller listens for changes to
the application state. The problem is that we never
disconnect this connection again. So if a screen is removed, and
the corresponing view controller is deallocated, the
connection is still kept alive. This will cause crashes to
occur when the signal emits, since the slot will then be accessing
deleted memory.

Fixes: QTBUG-76948
Change-Id: I758e51af9297cd62de193aae825f4475a2c7c3e5
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit d829d54a42393d797c5f6ab3b80e88df35fad1e4)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Richard Moe Gustavsen 2021-06-14 14:22:48 +02:00 committed by Qt Cherry-pick Bot
parent a225719ae8
commit 51838c964f

View File

@ -248,6 +248,7 @@
@implementation QIOSViewController { @implementation QIOSViewController {
BOOL m_updatingProperties; BOOL m_updatingProperties;
QMetaObject::Connection m_focusWindowChangeConnection; QMetaObject::Connection m_focusWindowChangeConnection;
QMetaObject::Connection m_appStateChangedConnection;
} }
#ifndef Q_OS_TVOS #ifndef Q_OS_TVOS
@ -276,7 +277,7 @@
}); });
QIOSApplicationState *applicationState = &QIOSIntegration::instance()->applicationState; QIOSApplicationState *applicationState = &QIOSIntegration::instance()->applicationState;
QObject::connect(applicationState, &QIOSApplicationState::applicationStateDidChange, m_appStateChangedConnection = QObject::connect(applicationState, &QIOSApplicationState::applicationStateDidChange,
[self](Qt::ApplicationState oldState, Qt::ApplicationState newState) { [self](Qt::ApplicationState oldState, Qt::ApplicationState newState) {
if (oldState == Qt::ApplicationSuspended && newState != Qt::ApplicationSuspended) { if (oldState == Qt::ApplicationSuspended && newState != Qt::ApplicationSuspended) {
// We may have ignored an earlier layout because the application was suspended, // We may have ignored an earlier layout because the application was suspended,
@ -296,6 +297,7 @@
- (void)dealloc - (void)dealloc
{ {
QObject::disconnect(m_focusWindowChangeConnection); QObject::disconnect(m_focusWindowChangeConnection);
QObject::disconnect(m_appStateChangedConnection);
[super dealloc]; [super dealloc];
} }