QtQml: Reset context object when destroying it from QObjectWrapper
There may be other objects that still hold on to the context data. We
should not leave them with a dangling context obejct.
Fixes: QTBUG-116228
Change-Id: I3dddd20b13956408d0e66c3a46e59377e45d91e5
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
(cherry picked from commit 1d3385e988
)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
7f22f9de5f
commit
c2c8369835
|
@ -1383,6 +1383,8 @@ void QObjectWrapper::destroyObject(bool lastCall)
|
|||
if (ddata && ddata->ownContext) {
|
||||
Q_ASSERT(ddata->ownContext.data() == ddata->context);
|
||||
ddata->ownContext->emitDestruction();
|
||||
if (ddata->ownContext->contextObject() == o)
|
||||
ddata->ownContext->setContextObject(nullptr);
|
||||
ddata->ownContext.reset();
|
||||
ddata->context = nullptr;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
import QtQml
|
||||
QtObject {
|
||||
property Component c: MyItem {}
|
||||
property QtObject o: c.createObject()
|
||||
}
|
|
@ -51,6 +51,7 @@ private slots:
|
|||
void destroyContextProperty();
|
||||
|
||||
void numericContextProperty();
|
||||
void gcDeletesContextObject();
|
||||
|
||||
private:
|
||||
QQmlEngine engine;
|
||||
|
@ -989,6 +990,33 @@ void tst_qqmlcontext::numericContextProperty()
|
|||
QCOMPARE(context->contextProperty(QLatin1String("11")).toInt(), 42);
|
||||
}
|
||||
|
||||
void tst_qqmlcontext::gcDeletesContextObject()
|
||||
{
|
||||
QQmlEngine engine;
|
||||
QQmlComponent c(&engine, testFileUrl("gcDeletesContextObject.qml"));
|
||||
|
||||
QVERIFY2(c.isReady(), qPrintable(c.errorString()));
|
||||
QScopedPointer<QObject> o(c.create());
|
||||
|
||||
QVERIFY(!o.isNull());
|
||||
|
||||
QPointer<QObject> contextObject = o->property("o").value<QObject *>();
|
||||
QVERIFY(contextObject != nullptr);
|
||||
|
||||
QQmlData *data = QQmlData::get(contextObject);
|
||||
QVERIFY(data);
|
||||
QQmlRefPointer<QQmlContextData> context = data->ownContext;
|
||||
QVERIFY(context);
|
||||
QCOMPARE(context->contextObject(), contextObject);
|
||||
|
||||
o->setProperty("o", QVariant::fromValue<QObject *>(nullptr));
|
||||
QCOMPARE(o->property("o").value<QObject *>(), nullptr);
|
||||
engine.collectGarbage();
|
||||
|
||||
QTRY_VERIFY(contextObject.isNull());
|
||||
QCOMPARE(context->contextObject(), nullptr);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qqmlcontext)
|
||||
|
||||
#include "tst_qqmlcontext.moc"
|
||||
|
|
Loading…
Reference in New Issue