diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2014-06-29 15:47:04 +0800 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2018-05-11 08:51:43 +0000 |
commit | 9f5bd5ab102325b03c2afaae39c6927fa89a956c (patch) | |
tree | 88c1c4e07020e54545c7d82d8e2f42d767b2d022 /src/qml/qml/qqmlopenmetaobject.cpp | |
parent | 5132709440d9161aae5893341d9180137f1181d7 (diff) |
Fix storing QObject pointers in dynamic role models
Storing QObject pointers in a dynamic role model man end up crashing the
application once those objects get deleted.
As it looks impossible to make QVariant::fromValue<QObject*>(...) track
the life cycle in a binary compatible way, this patch fixes the crashes
by tracking with a QPointer at the level of QVariant storage. That's the
QQmlOpenMetaObject in the case of the dynamic role model. In principle a
similar approach is already in place for storage of QML declared
properties - this patch mirrors the approach.
Test cases provided by Ben Lau <xbenlau@gmail.com> and Chris Adams
<chris.adams@jollamobile.com>.
Task-number: QTBUG-35639
Change-Id: I0aee227cd2057654c2cb843c4ebb57ed2ec9a8bf
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlopenmetaobject.cpp')
-rw-r--r-- | src/qml/qml/qqmlopenmetaobject.cpp | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/qml/qml/qqmlopenmetaobject.cpp b/src/qml/qml/qqmlopenmetaobject.cpp index ff89278faf..ce5983e05c 100644 --- a/src/qml/qml/qqmlopenmetaobject.cpp +++ b/src/qml/qml/qqmlopenmetaobject.cpp @@ -187,14 +187,22 @@ public: struct Property { private: QVariant m_value; + QPointer<QObject> qobjectTracker; public: bool valueSet = false; - const QVariant &value() const { return m_value; } + QVariant value() const { + if (QMetaType::typeFlags(m_value.userType()) & QMetaType::PointerToQObject + && qobjectTracker.isNull()) + return QVariant::fromValue<QObject*>(nullptr); + return m_value; + } QVariant &valueRef() { return m_value; } void setValue(const QVariant &v) { m_value = v; valueSet = true; + if (QMetaType::typeFlags(v.userType()) & QMetaType::PointerToQObject) + qobjectTracker = m_value.value<QObject*>(); } }; |