-
Bug
-
Resolution: Done
-
P1: Critical
-
5.5.1
-
None
-
Windows 7 x64, GCC 4.9.2
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.