You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PPL时,是否需要将析构函数与异步函数进行同步?

处理ViewModel销毁时的订阅清理

这是一个很典型的ViewModel生命周期管理场景——当View导航离开时,ViewModel可能会被销毁,这时候必须妥善清理订阅的事件,避免内存泄漏或者后续触发无效回调。你给出的析构实现已经很稳妥了,我来帮你拆解下逻辑,再补充一些相关的实践建议:

首先看你提供的析构函数代码:

MyViewModel::~MyViewModel() {
    if (m_subscription) {
        if (m_contentChangedToken.Value != 0) {
            m_subscription->ContentChanged -= m_contentChangedToken;
            m_contentChangedToken.Value = 0;
        }
    }
}

核心逻辑解析

  • 先检查m_subscription是否有效(非空),这一步能避免空指针访问,是基础的安全校验
  • 接着判断m_contentChangedToken的Value是否不为0——这是在确认我们确实成功绑定过ContentChanged事件,不会执行无效的移除操作
  • 调用m_subscription->ContentChanged -= m_contentChangedToken,把之前注册的回调从事件中解绑,切断ViewModel和订阅源的关联
  • 最后把m_contentChangedToken.Value重置为0,明确标记这个订阅已经被清理,防止后续误操作

对应的ViewModel初始化流程

通常ViewModel创建后,会通过异步函数获取订阅实例并绑定事件,大致逻辑如下:

void MyViewModel::Initialize() {
    // 异步获取订阅实例
    GetSubscriptionAsync().then([this](std::shared_ptr<Subscription> subscription) {
        m_subscription = subscription;
        if (m_subscription) {
            // 绑定ContentChanged事件,保存订阅令牌
            m_contentChangedToken = m_subscription->ContentChanged += [this](const Content& newContent) {
                // 处理内容变化的业务逻辑
                UpdateDisplayContent(newContent);
            };
        }
    });
}

一些优化建议

  • 封装清理逻辑:如果ViewModel有多个订阅需要清理,可以把订阅清理的代码封装成一个私有方法(比如CleanupSubscriptions()),这样代码更整洁,也能在其他需要清理的场景(比如ViewModel的Uninitialize方法)复用
  • 智能指针优化:如果用std::shared_ptr管理m_subscription,可以省去手动空指针检查,但仍要保留令牌有效性的判断——因为智能指针非空不代表订阅令牌一定有效
  • 异步安全防护:在异步获取订阅的回调中,建议用std::weak_ptr捕获this,如果ViewModel在异步操作完成前就被销毁,能避免悬空指针访问:
    auto weakThis = std::weak_ptr<MyViewModel>(shared_from_this());
    GetSubscriptionAsync().then([weakThis](std::shared_ptr<Subscription> subscription) {
        if (auto strongThis = weakThis.lock()) {
            strongThis->m_subscription = subscription;
            // 后续绑定事件逻辑...
        }
    });
    

内容的提问来源于stack exchange,提问作者Craig

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:54:33