创建了错误报告: 也许他们找到了解决此问题的方法,而无需使用 hacky 变通办法
问题是循环引用:
创建对象时,循环引用会导致奇怪的行为。
TestObj1.qml
import QtQuick 2.0
QtObject {
property Item paps
property int myVal: { console.log('myVal'); paps.val }
}
TestObj2.qml
import QtQuick 2.0
Item {
id: root
property int val: { console.log('set val', root); return 42 }
Component.onCompleted: console.log('Constructed Object')
TestObj1 {
id: to1
paps: root
}
}
结果:
qml: myVal
qml: set val TestObj_QMLTYPE_4(0x2c0bafb0)
qml: set val TestObj_QMLTYPE_4(0x2c0bafb0)
qml: Constructed Object
造成这种情况的可能原因是,该语句{console.log('set val', root); return 42 }
尚未被处理,当它已经分配给 时myVal
,因此该语句被执行了两次。
虽然这在正常情况下没有问题,但它可能会导致问题,只要我们没有在这些属性中动态创建对象。
TestObj3.qml
import QtQuick 2.0
Item {
id: root
property QtObject obj: { console.log('set obj'); return objPrototype.createObject(root) }
Component.onCompleted: console.log('Constructed Object', obj)
TestObj4 {
id: to1
paps: root
}
Component {
id: objPrototype
QtObject {
id: op
Component.onCompleted: console.log('PropertyObject created', op)
}
}
}
TestObj4.qml
import QtQuick 2.0
QtObject {
property Item paps
property QtObject myObj: paps.obj
Component.onCompleted: console.log(myObj)
}
结果:
qml: set obj
qml: PropertyObject created QObject(0x2c124708)
qml: set obj
qml: PropertyObject created QObject(0x2c1246f8)
qml: Constructed Object QObject(0x2c1246f8)
qml: QObject(0x2c1246f8)
所以你可以看到,这个对象确实被创建了两次。
有一些解决方法:
- 不要使用循环引用——但这会很无聊。
- 不要使用动态对象创建,因为它总是会产生问题- 我可以只创建对象,然后使用
property alias obj: myObjectID
或property QtObject obj: myObjectID
. 这有一个缺点,如果组件是可重用的,用户就不能替换那个对象或者对象仍然被创建,浪费内存。
Component.onCompleted
如果属性仍然为空(未被可重用组件的用户覆盖),则分配属性。这有一个缺点,即对象不可用,创建时Can't read property ... of null
会出现很多错误。他们希望不会破坏应用程序。
- 创建一个讨厌的绑定循环写:
property QtObject obj: (obj ? obj : objPrototype.createObject(root))
。它会发出警告,但是来吧。这只是一个绑定循环,将被检测和破坏。
这些变通办法没有什么好处,但也许有用。