aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Ogilvie <colin.ogilvie@kdab.com>2017-06-02 11:35:07 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2018-07-05 19:59:37 +0000
commitd6a5e14cdd3f233f5df4419c51b1c273b6ea9fe3 (patch)
tree7d043e117139178735a06dfaceee047cd5c91578
parentdf8d59e4b4a486c189263d008d69e4f6c2467d12 (diff)
Don't leak components in QQuickLoader
Only create source component in loadFromSource if it does not already exist. Previously toggling the active status when loading from source would create a new source component every time active became true. [ChangeLog][QtQuick][Loader] Don't leak components when changing source url. Change-Id: I1e4cfd5613e3851fcb4f3f55e78981f7c070cc77 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
-rw-r--r--src/quick/items/qquickloader.cpp8
-rw-r--r--tests/auto/quick/qquickloader/tst_qquickloader.cpp53
2 files changed, 59 insertions, 2 deletions
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index ea6a63559a..b5ae41daef 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -112,6 +112,8 @@ void QQuickLoaderPrivate::clear()
q, SIGNAL(progressChanged()));
component->deleteLater();
component = nullptr;
+ } else if (component) {
+ component = nullptr;
}
componentStrongReference.clear();
source = QUrl();
@@ -438,7 +440,8 @@ void QQuickLoader::loadFromSource()
if (isComponentComplete()) {
QQmlComponent::CompilationMode mode = d->asynchronous ? QQmlComponent::Asynchronous : QQmlComponent::PreferSynchronous;
- d->component = new QQmlComponent(qmlEngine(this), d->source, mode, this);
+ if (!d->component)
+ d->component = new QQmlComponent(qmlEngine(this), d->source, mode, this);
d->load();
}
}
@@ -828,7 +831,8 @@ void QQuickLoader::componentComplete()
if (active()) {
if (d->loadingFromSource) {
QQmlComponent::CompilationMode mode = d->asynchronous ? QQmlComponent::Asynchronous : QQmlComponent::PreferSynchronous;
- d->component = new QQmlComponent(qmlEngine(this), d->source, mode, this);
+ if (!d->component)
+ d->component = new QQmlComponent(qmlEngine(this), d->source, mode, this);
}
d->load();
}
diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
index 7a176661e8..5c3729a8cd 100644
--- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp
+++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
@@ -126,6 +126,8 @@ private slots:
void parentErrors();
void rootContext();
+ void sourceURLKeepComponent();
+
};
Q_DECLARE_METATYPE(QList<QQmlError>)
@@ -1388,6 +1390,57 @@ void tst_QQuickLoader::rootContext()
QCOMPARE(objectInRootContext.didIt, 2);
}
+void tst_QQuickLoader::sourceURLKeepComponent()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData(QByteArray(
+ "import QtQuick 2.0\n"
+ " Loader { id: loader\n }"),
+ dataDirectoryUrl());
+
+ QScopedPointer<QQuickLoader> loader(qobject_cast<QQuickLoader*>(component.create()));
+ loader->setSource(testFileUrl("/Rect120x60.qml"));
+
+ QVERIFY(loader);
+ QVERIFY(loader->item());
+ QVERIFY(loader->sourceComponent());
+ QCOMPARE(loader->progress(), 1.0);
+
+ const QPointer<QQmlComponent> sourceComponent = loader->sourceComponent();
+
+ //Ensure toggling active status does not recreate component
+ loader->setActive(false);
+ QVERIFY(!loader->item());
+ QVERIFY(loader->sourceComponent());
+ QCOMPARE(sourceComponent.data(), loader->sourceComponent());
+
+ loader->setActive(true);
+ QVERIFY(loader->item());
+ QVERIFY(loader->sourceComponent());
+ QCOMPARE(sourceComponent.data(), loader->sourceComponent());
+
+ loader->setActive(false);
+ QVERIFY(!loader->item());
+ QVERIFY(loader->sourceComponent());
+ QCOMPARE(sourceComponent.data(), loader->sourceComponent());
+
+ //Ensure changing source url causes component to be recreated when inactive
+ loader->setSource(testFileUrl("/BlueRect.qml"));
+
+ loader->setActive(true);
+ QVERIFY(loader->item());
+ QVERIFY(loader->sourceComponent());
+
+ const QPointer<QQmlComponent> newSourceComponent = loader->sourceComponent();
+ QVERIFY(sourceComponent.data() != newSourceComponent.data());
+
+ //Ensure changing source url causes component to be recreated when active
+ loader->setSource(testFileUrl("/Rect120x60.qml"));
+ QVERIFY(loader->sourceComponent() != newSourceComponent.data());
+
+}
+
QTEST_MAIN(tst_QQuickLoader)
#include "tst_qquickloader.moc"