谁拥有QQmlIncubator返回的对象?

时间:2017-05-05 18:11:03

标签: c++ qt qml

在以下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超出了范围,我只保留componentobject,都是它们包含类的实例变量,我在析构函数中调用delete component。我清理得好吗?

object属于component吗? object何时被销毁?

更新1

请参阅我的后续问题:http://doc.qt.io/qt-5/qqmlcomponent.html#create

2 个答案:

答案 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;
}