在以下C ++代码中,使用QQmlIncubator
创建QML组件。 Qt文档中包含此代码段http://doc.qt.io/qt-5/qqmlincubator.html:
QQmlIncubator incubator;
component->create(incubator);
while (!incubator.isReady()) {
QCoreApplication::processEvents(QEventLoop::AllEvents, 50);
}
// Who owns 'object'? When is it deleted?
QObject *object = incubator.object();
我的理解是这个代码段并不完整,因为您需要在组件上调用delete
。根据{{3}},QQmlComponent::create()
函数将返回的对象实例的所有权转移给调用者。好到目前为止。
现在我的问题是 - 谁在上面的代码段中拥有object
?在我的情况下,我将上面的代码段放在一个类的成员函数中,因此QQmlIncubator incubator
超出了范围,我只保留component
和object
,都是它们包含类的实例变量,我在析构函数中调用delete component
。我清理得好吗?
object
属于component
吗? object
何时被销毁?
答案 0 :(得分:2)
简短回答
您应该破坏孵育的对象(如果孵化器成功完成),否则会发生内存泄漏。
如何管理所有权?
一种好的方法可能是使用object parent将所有权转移到QObject::setParent
,例如转移到visual parent。这也是done by Qt when you construct QML objects in the traditional way:
分配给项目data属性的任何对象都成为该项目的子项 其QObject层次结构中的项目,用于内存管理。
为方便起见,Item data属性为default property。
<强>推理强>
如QQmlComponent::create(QQmlContext *)
文档中所述,对象所有权转移给用户:
返回的对象实例的所有权将传输给调用者。
因此,重载函数QQmlComponent::create(QQmlIncubator &incubator, QQmlContext *context, QQmlContext *forContext)
不太可能保留所有权,尽管文档中没有明确提及。有人可能会说所有权转移到QQmlIncubator
对象。只要组件为Loading
,就会出现这种情况,一旦准备好,所有权就会被QQmlIncubator::clear
中的(隐式)文档发布:
任何正在进行的孵化都会中止。如果孵化器处于就绪状态,则创建的对象不已删除。
请注意,在QQmlIncubator::clear
的析构函数内调用QQmlIncubator
。
答案 1 :(得分:2)
正如您的示例中所述,目前您负责object
销毁。很可能您需要通过调用setParent()
上的object
来处理这一问题,从而将责任转交给父项。
正如您指出component->create()
:
返回的对象实例的所有权转移到 呼叫者。
并且孵化器给出了保留该意图的所有外观。
验证这一点的实验方法是检查孵化器返回的object
的父级。
另一种验证方法是直接查看Qt中的相关源代码。以下是QQmlIncubator
的文件:
https://github.com/qt/qtdeclarative/blob/dev/src/qml/qml/qqmlincubator.cpp https://github.com/qt/qtdeclarative/blob/dev/src/qml/qml/qqmlincubator_p.h https://github.com/qt/qtdeclarative/blob/dev/src/qml/qml/qqmlincubator.h
检查这些文件时,删除结果的唯一位置是::clear
方法:
if (s == Loading) {
Q_ASSERT(d->compilationUnit);
if (d->result) d->result->deleteLater();
d->result = 0;
}