aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlmodels/qqmltableinstancemodel.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2025-11-18 10:53:09 +0100
committerUlf Hermann <ulf.hermann@qt.io>2025-11-28 15:41:49 +0100
commite4db77906b3f8bdcbe2ee20ff62ad818c6817e24 (patch)
treee924c17f3aa8e9fa07c168e50553e013740c0848 /src/qmlmodels/qqmltableinstancemodel.cpp
parent985ff60882d8c1e461f387464ac3c29083088750 (diff)
QmlModels: Split QQmlDelegateModelItem::m_objectRef
We need strong references for the cases where we place guards on the stack to prevent the deletion of the objects, and weak references we hand out to the view. The views don't systematically track the objects they hold and generally use a QPointer as second line of defence. In certain cases we cannot avoid deleting objects that are in fact still referenced as the clearObjectWeakReferences() call shows. If the QQmlDelegateModel itself is deleted while some view still holds a weak reference to an object, we cannot avoid deleting that object, no matter if the view agrees. Also, we can do with 16bit numbers for the references. The guards on the stack are rather few and you'll overflow the stack before you hit the 16bit maximum. The references handed out to the views are generally one or two per item. Task-number: QTBUG-141963 Change-Id: Ifb79e993abcaf4c169b08641ebc2a6378e0a4776 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qmlmodels/qqmltableinstancemodel.cpp')
-rw-r--r--src/qmlmodels/qqmltableinstancemodel.cpp25
1 files changed, 11 insertions, 14 deletions
diff --git a/src/qmlmodels/qqmltableinstancemodel.cpp b/src/qmlmodels/qqmltableinstancemodel.cpp
index 5cd5d4be15..7c38ff4116 100644
--- a/src/qmlmodels/qqmltableinstancemodel.cpp
+++ b/src/qmlmodels/qqmltableinstancemodel.cpp
@@ -59,7 +59,8 @@ QQmlTableInstanceModel::~QQmlTableInstanceModel()
// No item in m_modelItems should be referenced at this point. The view
// should release all its items before it deletes this model. Only model items
// that are still being incubated should be left for us to delete.
- Q_ASSERT(modelItem->objectRef() == 0);
+ // We can't rely on that, though. So we only check the strong ref.
+ Q_ASSERT(modelItem->objectStrongRef() == 0);
Q_ASSERT(modelItem->incubationTask());
// Check that we are not being deleted while we're
// in the process of e.g emitting a created signal.
@@ -130,12 +131,10 @@ QObject *QQmlTableInstanceModel::object(int index, QQmlIncubator::IncubationMode
if (!modelItem)
return nullptr;
- if (QObject *object = modelItem->object()) {
- // The model item has already been incubated. So
- // just bump the ref-count and return it.
- modelItem->referenceObject();
- return object;
- }
+ // The model item has already been incubated. So
+ // just bump the ref-count and return it.
+ if (modelItem->object())
+ return modelItem->referenceObjectWeak();
// The object is not ready, and needs to be incubated
incubateModelItem(modelItem, incubationMode);
@@ -145,11 +144,9 @@ QObject *QQmlTableInstanceModel::object(int index, QQmlIncubator::IncubationMode
// Incubation is done, so the task should be removed
Q_ASSERT(!modelItem->incubationTask());
- if (QObject *object = modelItem->object()) {
- // Incubation was completed sync and successful
- modelItem->referenceObject();
- return object;
- }
+ // Incubation was completed sync and successful
+ if (modelItem->object())
+ return modelItem->referenceObjectWeak();
// The object was incubated synchronously (otherwise we would return above). But since
// we have no object, the incubation must have failed. And when we have no object, there
@@ -171,7 +168,7 @@ QQmlInstanceModel::ReleaseFlags QQmlTableInstanceModel::release(QObject *object,
Q_ASSERT(m_modelItems.contains(modelItem->modelIndex()));
Q_ASSERT(m_modelItems[modelItem->modelIndex()]->object() == object);
- if (!modelItem->releaseObject())
+ if (!modelItem->releaseObjectWeak())
return QQmlDelegateModel::Referenced;
if (modelItem->isScriptReferenced()) {
@@ -213,7 +210,7 @@ void QQmlTableInstanceModel::dispose(QObject *object)
auto modelItem = qvariant_cast<QQmlDelegateModelItem *>(object->property(kModelItemTag));
Q_ASSERT(modelItem);
- modelItem->releaseObject();
+ modelItem->releaseObjectWeak();
// The item is not referenced by anyone
Q_ASSERT(!modelItem->isObjectReferenced());