diff options
5 files changed, 38 insertions, 0 deletions
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp index 7d04be2393..b83c21428c 100644 --- a/src/quick/items/qquickloader.cpp +++ b/src/quick/items/qquickloader.cpp @@ -106,6 +106,7 @@ void QQuickLoaderPrivate::clear() component->deleteLater(); component = 0; } + componentStrongReference.clear(); source = QUrl(); if (item) { @@ -472,6 +473,10 @@ void QQuickLoader::setSourceComponent(QQmlComponent *comp) d->clear(); d->component = comp; + if (comp) { + if (QQmlData *ddata = QQmlData::get(comp)) + d->componentStrongReference = ddata->jsWrapper.value(); + } d->loadingFromSource = false; if (d->active) diff --git a/src/quick/items/qquickloader_p_p.h b/src/quick/items/qquickloader_p_p.h index 9c94b4ce38..32c271222d 100644 --- a/src/quick/items/qquickloader_p_p.h +++ b/src/quick/items/qquickloader_p_p.h @@ -106,6 +106,7 @@ public: QQuickItem *item; QObject *object; QQmlComponent *component; + QV4::PersistentValue componentStrongReference; // To ensure GC doesn't delete components created by Qt.createComponent QQmlContext *itemContext; QQuickLoaderIncubator *incubator; QV4::PersistentValue initialPropertyValues; 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<QObject> 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" |