From adaedcb9ead1c536ff3d8fba0fb9f4fc262d4d45 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 5 Dec 2013 16:21:03 +0100 Subject: Fix crash in QQuickLoader when source component is garbage collected It may happen that the QQuickLoader is the last entity left in the system holding a reference to the QQmlComponent *sourceComponent. We have to let the garbage collector know about that by keeping a persistent value for it. Task-number: QTBUG-35334 Change-Id: I715864440378fd9dd4f2d5ef8ff2f171c81ed7ef Reviewed-by: Lars Knoll --- .../qquickloader/data/SimpleTestComponent.qml | 2 ++ .../data/sourceComponentGarbageCollection.qml | 8 ++++++++ tests/auto/quick/qquickloader/tst_qquickloader.cpp | 22 ++++++++++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 tests/auto/quick/qquickloader/data/SimpleTestComponent.qml create mode 100644 tests/auto/quick/qquickloader/data/sourceComponentGarbageCollection.qml (limited to 'tests') diff --git a/tests/auto/quick/qquickloader/data/SimpleTestComponent.qml b/tests/auto/quick/qquickloader/data/SimpleTestComponent.qml new file mode 100644 index 0000000000..0e69012662 --- /dev/null +++ b/tests/auto/quick/qquickloader/data/SimpleTestComponent.qml @@ -0,0 +1,2 @@ +import QtQml 2.0 +QtObject {} diff --git a/tests/auto/quick/qquickloader/data/sourceComponentGarbageCollection.qml b/tests/auto/quick/qquickloader/data/sourceComponentGarbageCollection.qml new file mode 100644 index 0000000000..ab86883af5 --- /dev/null +++ b/tests/auto/quick/qquickloader/data/sourceComponentGarbageCollection.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +Loader { + active: false + function setSourceComponent() { + sourceComponent = Qt.createComponent("SimpleTestComponent.qml"); + } +} diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp index 50ded4d95a..1e23d689ff 100644 --- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp +++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp @@ -128,6 +128,8 @@ private slots: void sizeBound(); void QTBUG_30183(); + void sourceComponentGarbageCollection(); + private: QQmlEngine engine; }; @@ -1144,6 +1146,26 @@ void tst_QQuickLoader::QTBUG_30183() delete loader; } +void tst_QQuickLoader::sourceComponentGarbageCollection() +{ + QQmlComponent component(&engine, testFileUrl("sourceComponentGarbageCollection.qml")); + QScopedPointer obj(component.create()); + QVERIFY(!obj.isNull()); + + QMetaObject::invokeMethod(obj.data(), "setSourceComponent"); + engine.collectGarbage(); + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + + QSignalSpy spy(obj.data(), SIGNAL(loaded())); + + obj->setProperty("active", true); + + if (spy.isEmpty()) + QVERIFY(spy.wait()); + + QCOMPARE(spy.count(), 1); +} + QTEST_MAIN(tst_QQuickLoader) #include "tst_qquickloader.moc" -- cgit v1.2.3