QObject :: deleteLater没有在我的Qt测试中按预期方式被调用

时间:2018-09-19 12:26:06

标签: c++ qt qtestlib

我正在测试一个共享库,该库在内部包含对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时不会调用它。

但是,如果我执行两次测试(通过添加作为test1副本的test2插槽),那么它将被调用一次。

我的理解是,当信号发出时,它会停止间谍事件循环,然后再也不会调用deleteLater。 在第二个事件循环在test2中开始之后,它将处理从先前的test1中挂起的删除操作。

对吗? 谢谢。

1 个答案:

答案 0 :(得分:1)

是的,您是对的。由于row_numberdelete from ( select * ,row_number() over(partition by ProgramCode, VIN, ValidFrom order by Creation_date desc) as rn ) as t where t.rn!=1 处于同一线程中,因此信号QSignalSpy不会通过事件循环传递,而是通过直接连接传递。因此,事件循环在Foo中发出信号后立即停止。但是,由于mySignal是由同一事件循环调用的,因此控制仅在myslot返回时才返回。因此,当事件循环有可能执行myslot请求的清除时,它已经停止了。

如果您要测试myslot是否已正确清理,则可以创建一个附加的deleteLater并将其连接到m_obj信号上,每个QSignalSpy都会发出信号被摧毁。

但是,您需要在构造函数中或通过setter传入QObject::destroyed作为对QObject的依赖,而不是在m_obj本身中构造它。

然后测试可能看起来像这样:

Foo