我正在测试一个共享库,该库在内部包含对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中挂起的删除操作。
对吗? 谢谢。
答案 0 :(得分:1)
是的,您是对的。由于row_number
和delete 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