Details
-
Bug
-
Resolution: Done
-
P1: Critical
-
5.5.1
-
None
-
Windows 7 x64, GCC 4.9.2
Description
The QML engine appears to have a bug in object lifetime management. According to the documentation, an object will not be collected if it either has a parent or is referenced by the JS engine.
Yet in the following example, objects are deleted while still matching those two requirements. Objects are properly parented and referenced by JS code when they get deleted:
/ ObjMain.qml Item { property ListModel list : ListModel { } Component.onCompleted: console.log("created " + this + " with parent " + parent) Component.onDestruction: console.log("deleted " + this) } // Uimain.qml Item { id: main width: childrenRect.width height: childrenRect.height property Item object property bool expanded : true Loader { id: li x: 50 y: 50 active: expanded && object && object.list.count width: childrenRect.width height: childrenRect.height sourceComponent: listView } Component { id: listView ListView { width: contentItem.childrenRect.width height: contentItem.childrenRect.height model: object.list delegate: Item { id: p width: childrenRect.width height: childrenRect.height Component.onCompleted: Qt.createComponent("Uimain.qml").createObject(p, {"object" : o}) } } } Rectangle { width: 50 height: 50 color: "red" MouseArea { anchors.fill: parent acceptedButtons: Qt.RightButton | Qt.LeftButton onClicked: { if (mouse.button == Qt.RightButton) { expanded = !expanded } else { object.list.append({ "o" : Qt.createComponent("ObjMain.qml").createObject(object) }) } } } } } // main.qml Window { visible: true width: 1280 height: 720 ObjMain { id: obj } Uimain { object: obj } }
The example is a trivial object tree builder, with the left button adding a leaf to the node and the right button collapsing the node. All it takes to reproduce the bug is to create a node with depth of 3 and then collapse and expand the root node, upon which the console output shows:
qml: created ObjMain_QMLTYPE_0(0x1e15bb8) with parent QQuickRootItem(0x1e15ca8) qml: created ObjMain_QMLTYPE_0(0x1e5afc8) with parent ObjMain_QMLTYPE_0(0x1e15bb8) qml: created ObjMain_QMLTYPE_0(0x1e30f58) with parent ObjMain_QMLTYPE_0(0x1e5afc8) qml: deleted ObjMain_QMLTYPE_0(0x1e30f58)
This is just one of the several cases I experienced arbitrary object deletions, such happen to both objects, returned from C++ and objects, created entirely in QML. In this particular case the deletion seems to be connected to where createObject() is being called - if instead in the UI the objects is created in a function in main.qml, which is called in the UI then the deletion does not take place. However, I wasn't able to pinpoint any such dependencies in the other cases of arbitrary object deletion.