aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/types/qqmllistmodel.cpp10
-rw-r--r--tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp28
2 files changed, 35 insertions, 3 deletions
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index 2b4e906617..efc61d7cdd 100644
--- a/src/qml/types/qqmllistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -255,7 +255,12 @@ QObject *ListModel::getOrCreateModelObject(QQmlListModel *model, int elementInde
{
ListElement *e = elements[elementIndex];
if (e->m_objectCache == 0) {
- e->m_objectCache = new QObject;
+ void *memory = operator new(sizeof(QObject) + sizeof(QQmlData));
+ void *ddataMemory = ((char *)memory) + sizeof(QObject);
+ e->m_objectCache = new (memory) QObject;
+ QQmlData *ddata = new (ddataMemory) QQmlData;
+ ddata->ownMemory = false;
+ QObjectPrivate::get(e->m_objectCache)->declarativeData = ddata;
(void)new ModelNodeMetaObject(e->m_objectCache, model, elementIndex);
}
return e->m_objectCache;
@@ -2292,8 +2297,7 @@ QQmlV4Handle QQmlListModel::get(int index) const
QObject *object = m_listModel->getOrCreateModelObject(const_cast<QQmlListModel *>(this), index);
result = scope.engine->memoryManager->allocObject<QV4::ModelObject>(object, const_cast<QQmlListModel *>(this), index);
// Keep track of the QObjectWrapper in persistent value storage
- QV4::Value *val = scope.engine->memoryManager->m_weakValues->allocate();
- *val = result;
+ QQmlData::get(object)->jsWrapper.set(scope.engine, result);
}
}
diff --git a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
index f5c0e5ddf7..653e7543c0 100644
--- a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
+++ b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
@@ -124,6 +124,7 @@ private slots:
void modify_through_delegate();
void bindingsOnGetResult();
void stringifyModelEntry();
+ void qobjectTrackerForDynamicModelObjects();
};
bool tst_qqmllistmodel::compareVariantList(const QVariantList &testList, QVariant object)
@@ -1505,6 +1506,33 @@ void tst_qqmllistmodel::stringifyModelEntry()
QCOMPARE(v.toString(), expectedString);
}
+void tst_qqmllistmodel::qobjectTrackerForDynamicModelObjects()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "Item {\n"
+ " ListModel {\n"
+ " id: testModel\n"
+ " objectName: \"testModel\"\n"
+ " ListElement { name: \"Joe\"; age: 22 }\n"
+ " }\n"
+ "}\n", QUrl());
+ QScopedPointer<QObject> scene(component.create());
+ QQmlListModel *model = scene->findChild<QQmlListModel*>("testModel");
+ QQmlExpression expr(engine.rootContext(), model, "get(0);");
+ QVariant v = expr.evaluate();
+ QVERIFY2(!expr.hasError(), QTest::toString(expr.error().toString()));
+
+ QObject *obj = v.value<QObject*>();
+ QVERIFY(obj);
+
+ QQmlData *ddata = QQmlData::get(obj, /*create*/false);
+ QVERIFY(ddata);
+ QVERIFY(!ddata->jsWrapper.isNullOrUndefined());
+}
+
QTEST_MAIN(tst_qqmllistmodel)
#include "tst_qqmllistmodel.moc"