Skip to content

Commit d286eca

Browse files
committed
fix: prevent crashes and memory leaks during object lifecycle
Add batch update flag to suppress intermediate signals during page navigation, add null checks for parent private pointer in DccObject, and fix component memory leaks when plugin manager is deleting. 添加批量更新标志以抑制页面导航期间的中间信号发射, 增加 DccObject 父对象私有指针的空检查,修复插件管理器 删除时的组件内存泄漏问题。 Log: 修复对象生命周期中的崩溃和内存泄漏问题 PMS: BUG-335919 Influence: 修复控制中心页面切换过程中可能出现的崩溃问题, 修复插件卸载时的内存泄漏,提升稳定性。
1 parent 1f42242 commit d286eca

6 files changed

Lines changed: 41 additions & 8 deletions

File tree

src/dde-control-center/dccmanager.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,8 @@ void DccManager::doShowPage(QPointer<DccObject> obj, const QString &cmd)
837837
if (triggeredObj->pageType() == DccObject::MenuEditor && !triggeredObj->getChildren().isEmpty()) {
838838
triggeredObj = triggeredObj->getChildren().first();
839839
}
840+
841+
m_batchUpdating = true;
840842
DccObject *tmpObj = triggeredObj;
841843
tmpObj->setCurrentObject(nullptr);
842844
tmpObj->active(QString());
@@ -850,6 +852,7 @@ void DccManager::doShowPage(QPointer<DccObject> obj, const QString &cmd)
850852
tmpObj = tmpObjParent;
851853
}
852854
if (!tmpObj) {
855+
m_batchUpdating = false;
853856
return;
854857
}
855858
modules.append(tmpObj);
@@ -881,6 +884,8 @@ void DccManager::doShowPage(QPointer<DccObject> obj, const QString &cmd)
881884
// 更新当前对象
882885
m_currentObjects = modules;
883886
m_triggeredObjects = triggeredObjs;
887+
m_batchUpdating = false;
888+
884889
Q_EMIT triggeredObjectsChanged(m_triggeredObjects);
885890
if (auto *lastObj = m_currentObjects.last(); lastObj != m_activeObject) {
886891
m_activeObject = lastObj;

src/dde-control-center/dccmanager.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <QDBusContext>
1313
#include <QDBusMessage>
1414
#include <QObject>
15+
#include <atomic>
1516

1617
QT_BEGIN_NAMESPACE
1718
class QWindow;
@@ -52,6 +53,8 @@ class DccManager : public DccApp, protected QDBusContext
5253

5354
inline const QVector<DccObject *> &triggeredObjects() const override { return m_triggeredObjects; }
5455

56+
inline bool isBatchUpdating() const override { return m_batchUpdating; }
57+
5558
Q_INVOKABLE DccApp::UosEdition uosEdition() const;
5659
Q_INVOKABLE Dtk::Core::DSysInfo::ProductType productType() const;
5760

@@ -145,6 +148,7 @@ private Q_SLOTS:
145148
QDBusMessage m_showMessage;
146149

147150
QHash<QString, QVector<DccObject *>> m_objMap; // 映射对象名称到对象指针列表,用于快速查找
151+
std::atomic<bool> m_batchUpdating{false};
148152
};
149153
} // namespace dccV25
150154
#endif // DCCMANAGER_H

src/dde-control-center/plugin/DccLoader.qml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,17 @@ Loader {
77
property Item dccObjItem: null
88

99
function updateDccObjItem() {
10-
if (dccObj) {
10+
if (dccObj && dccObjItem) {
1111
dccObj.parentItem = dccObjItem
1212
}
1313
}
14+
15+
Component.onDestruction: {
16+
if (dccObj && dccObj.parentItem === dccObjItem) {
17+
dccObj.parentItem = null
18+
}
19+
}
20+
1421
enabled: dccObj && dccObj.enabledToApp
1522
// asynchronous: true
1623
sourceComponent: dccObj ? dccObj.page : null

src/dde-control-center/plugin/dccapp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ class DccApp : public QObject
6262
virtual void setSidebarWidth(int width);
6363
virtual void setAnimationMode(AnimationMode mode);
6464

65+
virtual bool isBatchUpdating() const { return false; }
66+
6567
public Q_SLOTS:
6668
virtual DccObject *object(const QString &name);
6769
virtual void addObject(DccObject *obj);

src/dde-control-center/plugin/dccobject.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// SPDX-License-Identifier: GPL-3.0-or-later
44
#include "dccobject.h"
55

6+
#include "dccapp.h"
67
#include "dccobject_p.h"
78

89
#include <QLoggingCategory>
@@ -45,7 +46,7 @@ DccObject::Private::~Private()
4546
m_page->deleteLater();
4647
m_page = nullptr;
4748
}
48-
if (m_parent) {
49+
if (m_parent && m_parent->p_ptr) {
4950
m_parent->p_ptr->removeChild(q_ptr);
5051
}
5152
while (!m_children.isEmpty()) {
@@ -177,7 +178,7 @@ const QVector<DccObject *> &DccObject::Private::getChildren() const
177178

178179
int DccObject::Private::getIndex() const
179180
{
180-
return m_parent ? m_parent->p_ptr->getChildren().indexOf(q_ptr) : -1;
181+
return (m_parent && m_parent->p_ptr) ? m_parent->p_ptr->getChildren().indexOf(q_ptr) : -1;
181182
}
182183

183184
DccObject *DccObject::Private::getChild(int childPos) const
@@ -295,7 +296,7 @@ void DccObject::setWeight(quint32 weight)
295296
{
296297
if (p_ptr->m_weight != weight) {
297298
p_ptr->m_weight = weight;
298-
if (p_ptr->m_parent) {
299+
if (p_ptr->m_parent && p_ptr->m_parent->p_ptr) {
299300
p_ptr->m_parent->p_ptr->updatePos(this);
300301
}
301302
Q_EMIT weightChanged(p_ptr->m_weight);
@@ -442,11 +443,16 @@ DccObject *DccObject::currentObject()
442443
void DccObject::setCurrentObject(DccObject *obj)
443444
{
444445
if (p_ptr->m_currentObject != obj) {
445-
if (p_ptr->m_currentObject) {
446-
Q_EMIT p_ptr->m_currentObject->deactive();
447-
}
446+
DccObject *oldObject = p_ptr->m_currentObject;
448447
p_ptr->m_currentObject = obj;
449-
Q_EMIT currentObjectChanged(p_ptr->m_currentObject);
448+
449+
DccApp *app = DccApp::instance();
450+
if (!app || !app->isBatchUpdating()) {
451+
if (oldObject) {
452+
Q_EMIT oldObject->deactive();
453+
}
454+
Q_EMIT currentObjectChanged(p_ptr->m_currentObject);
455+
}
450456
}
451457
}
452458

src/dde-control-center/pluginmanager.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@ void LoadPluginTask::createData()
151151
soObj->setParent(nullptr);
152152
}
153153
}
154+
if (m_pManager->isDeleting()) {
155+
if (dataObj)
156+
delete dataObj;
157+
if (soObj)
158+
delete soObj;
159+
return;
160+
}
154161
if (dataObj) {
155162
m_data->data = dataObj;
156163
}
@@ -507,6 +514,7 @@ void PluginManager::loadMain(PluginData *plugin)
507514
void PluginManager::createModule(QQmlComponent *component)
508515
{
509516
if (isDeleting()) {
517+
component->deleteLater();
510518
return;
511519
}
512520
PluginData *plugin = component->property("PluginData").value<PluginData *>();
@@ -536,6 +544,7 @@ void PluginManager::createModule(QQmlComponent *component)
536544
void PluginManager::createMain(QQmlComponent *component)
537545
{
538546
if (isDeleting()) {
547+
component->deleteLater();
539548
return;
540549
}
541550
PluginData *plugin = component->property("PluginData").value<PluginData *>();

0 commit comments

Comments
 (0)