5

我在模型视图设置中使用 RxCpp。视图更新方法订阅了一个可观察对象(通过 lambda 捕获this)。如果订阅比视图实例寿命更长,则会出现未定义的内存访问。我不希望订阅使视图保持活力。因此,我需要订阅在视图的析构函数上确定地结束。这听起来像是 RAII 的案例。

这会很危险吗?它是否以某种方式滥用了rx?我读过喜欢take_until在类似的设置。为什么会更好,如何在这里使用它?

谢谢!

#include "rxcpp/rx.hpp"

class MyView : public View
{
public:
    MyView(rxcpp::observable<int> obs) : obs (obs)
    {
        sub = obs.subscribe ([this] (int i) { update(i); });
    }
    ~MyView()
    {
        sub.unsubscribe();
    }
    void update(int i)
    {
        number = i;
        repaint();
    }
private:
    rxcpp::observable<int> obs;
    rxcpp::subscription sub;
    int number;
};
4

1 回答 1

1

take_until是在它之后组成下一个动作时的最佳答案。这将确保正确的排序。

问题是取消总是一场竞赛。问题中的代码在unsubscribe()析构函数中,这开始了取消比赛。但是,析构函数不会等到订阅结束。这在析构函数的退出和预期this有效的订阅结束之间留下了竞争。

解决方案是在unsubscribe().

这可能是对finally()在构造函数的原始订阅中设置的原子布尔值的忙等待。

mutex或者,使用 a和 a condition_variable(用于表示finally())可能会导致更重的等待condition_variable

于 2021-09-29T13:56:26.993 回答