gpt4 book ai didi

c++ - QObject::deleteLater 在我的 Qt 测试中没有按预期调用

转载 作者:行者123 更新时间:2023-11-28 04:32:54 24 4
gpt4 key购买 nike

我正在测试一个共享库,其中包含内部对 deleteLater 的调用。库中没有运行事件循环,因此应用程序需要运行事件循环,以便正确释放所有内存。

但是在测试中,对象dtor并没有像预期的那样被调用。

例如:

void test1() 
{
Foo foo;
QSignalSpy spy(&foo, SIGNAL(mySignal(Status)));

foo.do(); // should trigger mySignal

QVERIFY(spy.wait(10000)); // event loop started for 10 s max
QCOMPARE(spy.count(), 1);
QList<QVariant> sig = spy.takeFirst();
Foo::Status status = qvariant_cast<Foo::Status>(sig.at(0));

QVERIFY2(status == Foo:Ok, "Failed");
}

Foo 类看起来像这样:

class Foo : public QObject
{
Q_OBJECT

// ... methods, signals, slots..

private slots:
// this call is asynchronous (depends on a network reply)
void myslot() {
//..
m_obj->deleteLater();
emit mySignal(Foo:Ok);
}
};

我在 m_obj 的 dtor 中添加了一些调试打印,并且在执行 test1 时不会调用它。

但是,如果我执行两次测试(通过添加一个 test2 插槽,它是 test1 的拷贝),那么它会被调用一次。

我的理解是,当发出信号时,它会停止 spy 事件循环,然后永远不会调用 deleteLater。之后,第二个事件循环在 test2 中开始,它处理来自前一个 test1 的未决删除。

是否正确?谢谢。

最佳答案

是的,你是对的。由于 QSignalSpyFoo 存在于同一个线程中,因此信号 mySignal 不是通过事件循环传递的,而是通过直接连接传递的。因此,事件循环在 myslot 中发出信号后立即停止。然而,由于 myslot 被同一个事件循环调用,控制权仅在 myslot 返回时返回给它。因此,当事件循环可能执行 deleteLater 请求的清理时,它已经停止了。

如果你想测试 m_obj 是否被正确清理,你可以创建一个额外的 QSignalSpy 并将其连接到 QObject::destroyed 表示每个 QObject 在被销毁时都会发出信号。

但是,您需要将 m_obj 作为 Foo 的依赖项传递到构造函数中或通过 setter 而不是在 Foo< 中构造它 本身。

然后测试看起来像这样:

void test1()
{
auto obj = new Obj{}; // will be assigned to `Foo::m_obj`
Foo foo{obj};

QSignalSpy deletion_spy(obj, &QObject::destroyed);
QSignalSpy mysignal_spy(&Foo, &Foo::mySignal);

QVERIFY(deletion_spy.wait(10000));
QCOMPARE(deletion_spy.count(), 1); // verify that `obj` got deleted

QCOMPARE(mysignal_spy.count(), 1);
QList<QVariant> sig = spy.takeFirst();
Foo::Status status = qvariant_cast<Foo::Status>(sig.at(0));

QVERIFY2(status == Foo:Ok, "Failed");
}

关于c++ - QObject::deleteLater 在我的 Qt 测试中没有按预期调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52405841/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com