Skip to content

Conversation

@ut003640
Copy link
Contributor

在Qt6中,使用lambda作为槽函数,不能使用Qt::UniqueConnection,会导致崩溃

Log:
Influence: 更新信号
PMS: BUG-331547

在Qt6中,使用lambda作为槽函数,不能使用Qt::UniqueConnection,会导致崩溃

Log:
Influence: 更新信号
PMS: BUG-331547
Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @ut003640, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@deepin-ci-robot
Copy link

deepin pr auto review

这段代码主要涉及对 Qt 信号槽连接方式的修改,具体是将连接类型从 Qt::UniqueConnection 改为默认的自动连接。以下是对这段代码的详细审查和改进意见:

1. 语法与逻辑审查

  • 语法正确性:修改后的代码在 C++ 语法上是正确的。Lambda 表达式和 connect 函数的使用符合 Qt 规范。
  • 逻辑变更分析
    • 修改前:使用了 Qt::UniqueConnection。这意味着如果相同的信号(sender, signal, receiver, slot 完全一致)已经被连接过,Qt 不会重复建立连接。
    • 修改后:移除了 Qt::UniqueConnection,使用了默认的连接类型。
    • 潜在风险:这段代码位于一个 Lambda 表达式 changeActiveAp 中,而这个 Lambda 似乎是通过 connect 挂载在 activeAccessPointChanged 信号上的。
      • 如果 activeAccessPointChanged 信号被多次触发(例如网络切换频繁),changeActiveAp 就会被多次执行。
      • 每次执行 changeActiveAp 时,都会尝试连接 activeApsignalStrengthChanged 信号到 updateActiveApStrength
      • 关键问题:由于移除了 Qt::UniqueConnection,如果 activeAp 指针指向同一个对象(例如在同一个 AP 信号强度波动时,AP 对象未变),这会导致重复连接。结果是 updateActiveApStrength 被调用多次,造成逻辑冗余甚至性能问题。

2. 代码质量与改进意见

问题点:移除 Qt::UniqueConnection 极有可能导致信号槽的重复连接。

改进建议
建议恢复 Qt::UniqueConnection,或者采用更稳健的方式来管理连接的生命周期。

方案 A:恢复 Qt::UniqueConnection(最简单)

这是防止重复连接最直接的方法。

// ...
m_activeApStrengthConn = connect(activeAp.data(), &NetworkManager::AccessPoint::signalStrengthChanged, this, [updateActiveApStrength, activeAp] {
    updateActiveApStrength(activeAp);
}, Qt::UniqueConnection);
// ...

方案 B:显式断开旧连接(推荐,更清晰)

在类成员变量中维护这个连接(看起来代码中已经有了 m_activeApStrengthConn),在建立新连接之前,显式断开旧连接。这种方式逻辑最清晰,避免了依赖 Qt::UniqueConnection 的隐式行为,且能确保总是最新的 AP 在监控中。

// 1. 在类定义中确保有成员变量存储连接句柄
// QMetaObject::Connection m_activeApStrengthConn;

// 2. 在 changeActiveAp lambda 中
// 先断开之前的连接(如果存在)
if (m_activeApStrengthConn) {
    disconnect(m_activeApStrengthConn);
}

// 建立新连接(此时不需要 Qt::UniqueConnection,因为已经手动断开了旧的)
m_activeApStrengthConn = connect(activeAp.data(), &NetworkManager::AccessPoint::signalStrengthChanged, this, [updateActiveApStrength, activeAp] {
    updateActiveApStrength(activeAp);
});

3. 代码性能

  • 重复调用的开销:如果发生重复连接,每次 signalStrengthChanged 信号发出时,槽函数都会执行 N 次(N 为连接次数)。这会增加不必要的 CPU 开销。
  • Lambda 捕获:Lambda 按值捕获了 updateActiveApStrengthactiveApactiveApQSharedPointer 或类似的智能指针,按值捕获会增加引用计数,这是安全的,但需注意对象生命周期。

4. 代码安全

  • 对象生命周期(悬空指针风险)
    • Lambda 捕获了 activeAp。通常 activeAp 是一个智能指针(如 QSharedPointer),这能保证在槽执行时对象依然存活,是安全的。
    • 如果 activeAp 是裸指针,且在信号触发前对象被销毁,会导致崩溃。但在 NetworkManager 上下文中通常使用智能指针,这点通常是安全的。
  • this 指针:Lambda 中使用了 this(作为 receiver),这要求 WirelessDeviceManagerRealize 对象在信号触发时必须存在。如果 DeviceManager 先于 AccessPoint 被销毁,可能会有风险。通常由父对象管理子对象,问题不大。

总结

不建议采纳当前的 diff 修改。
移除 Qt::UniqueConnection 会引入重复连接的风险。
最佳实践是使用 方案 B:利用 m_activeApStrengthConn 成员变量,在连接新信号前显式 disconnect 旧连接。这样既保证了逻辑的清晰,也避免了重复连接带来的性能损耗。

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: caixr23, ut003640

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ut003640
Copy link
Contributor Author

/forcemerge

@deepin-bot
Copy link
Contributor

deepin-bot bot commented Jan 31, 2026

This pr force merged! (status: unstable)

@deepin-bot deepin-bot bot merged commit 2d0d9ed into linuxdeepin:master Jan 31, 2026
16 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants