![](/img/trans.png)
[英]What are the rules for a C++ object returned from a Q_INVOKABLE to be owned and collected by QML?
[英]QML QQmlPropertyList - contained object lifetimes and 'memory rules'
我发现很难确认将插入到QQmlPropertyList中的项目的对象所有权规则设置为C ++中定义的QML组件的一部分时,
Q_CLASSINFO("DefaultProperty", "values")
DTech在QQmlListProperty中询问了类似的问题-可写QList是否违反QML的内存管理规则? ,但他担心删除QML中定义的组件的后果。 通常,我更担心插入列表中的对象的生命周期要求。
现在从我的理解:
如果从QML创建并插入了子代,则将自动设置其父代,并由QmlEngine管理对象。 (父项应已在附加项上定义)
如果我从C ++端插入某些内容,则需要自己管理生命周期。 (父项将在附加时为nullptr)
QT文档警告不要“违反QML的内存管理规则”。 在http://doc.qt.io/qt-5/qqmllistproperty.html中,但是我找不到任何能以清晰,简洁的方式真正说明这些内容的内容。
目前,我已经围绕矢量实现了包装器,该包装器非常类似于http://doc.qt.io/qt-5/qtqml-referenceexamples-properties-example.html
但是我添加了两个规则:
我假设由于在添加具有nullptr父对象的对象时设置了父对象,因此当父对象超出范围时,QT将删除自动拥有的QObject 。
还有更多我想念的规则吗?
我的实施代码,以防万一以上需要澄清:
template <typename T>
class QmlListFacade {
private:
std::vector<T *> _storage;
static void append(QQmlListProperty<T> *list, T *newValue) {
// take ownership of the object if none are currently defined
auto obj = static_cast<QObject *>(newValue);
if( obj->parent() == nullptr) {
obj->setParent(list->object);
}
auto internalList = reinterpret_cast<QmlListFacade *>(list->data);
internalList->_storage.push_back(newValue);
}
static int count(QQmlListProperty<T> *list) {
return reinterpret_cast<QmlListFacade *>(list->data)->_storage.size();
}
static T *get(QQmlListProperty<T> *list, int index) {
return reinterpret_cast<QmlListFacade *>(list->data)->_storage[index];
}
static void clear(QQmlListProperty<T> *list) {
auto internalList = reinterpret_cast<QmlListFacade *>(list->data);
for( auto item :internalList->_storage){
// only delete if we are the owners.
auto obj = static_cast<QObject *>(item);
if( obj->parent() == list->object){
obj->setParent(nullptr);
obj->deleteLater();
}
}
return internalList->_storage.clear();
}
public:
QmlListFacade() = default;
QQmlListProperty<T> values(QObject *parent) {
return QQmlListProperty<T>(parent, this, &QmlListFacade::append, &QmlListFacade::count, &QmlListFacade::get,
&QmlListFacade::clear);
}
};
从发现QML脆弱的对象生命周期管理并为此奋斗了近3年的人的角度来看,在那种经验之窗中,我没有遇到任何处理声明性定义的对象树的情况。
问题在于动态创建的对象,这些对象有时会被删除,无论它们是否具有父对象或代码中存在多少对它们的有效引用。 如果要确保不会将其删除,请给他们明确的CPP所有权。
这样可以防止引擎在使用过程中破坏这些物体。 当对象的父对象销毁时,仍会收集对象,就像在C ++ API中那样。
请注意,此警告仅出现在接受QList
的构造函数中,而不包含接受控制功能指针的构造函数。 因此,如果您不使用该格式,则至少可以感到满意。 我对两者都进行了大量测试,因此没有遇到任何功能差异。 除了未提供任何含义和含义的上下文之外,该警告可能被放错了位置,措辞不佳甚至完全没有意义。 只是要彻底测试才能发现婴儿期的任何问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.