diff options
-rw-r--r-- | src/qml/types/qqmllistmodel.cpp | 10 | ||||
-rw-r--r-- | tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp | 28 |
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" |