在信号/时隙处理期间删除QObject

时间:2013-08-29 08:13:28

标签: c++ qt

我知道从插槽处理中删除QObject可能会导致应用程序崩溃,因为它可能有其他排队事件。 因此,我将使用obj-> deleteLater()而不是使用“删除obj”。据我所知,obj等待处理所有排队的事件,然后“删除obj”。

  

QObject :: ~QObject()   进出对象的所有信号都将自动断开,并且从事件队列中删除该对象的所有待处理发布事件。但是,使用deleteLater()而不是直接删除QObject子类通常更安全。

但是,其他信号/插槽流程是什么?我的意思是,如果你已经从作为Qt :: QueuedConnection或Qt :: BlockingQueuedConnection的不同线程中的对象连接了信号/槽。他们是否已经登记处理?

提前致谢。

2 个答案:

答案 0 :(得分:1)

deleteLater将从对象所属的线程中删除对象。 Qt::QueuedConnectionQt::BlockingQueuedConnection(也Qt::AutoConnection)以这种方式工作,即从带有插槽的对象所属的线程的事件循环调用插槽。
因此,如果您添加此引用,则表示当对象被销毁时,任何待处理的Qt::*QueuedConnection将自动被解除。这意味着在使用这些连接和deleteLater时您是安全的。当您将Qt::DirectConnection与不同的线程一起使用时,或者当您尝试从错误的线程直接销毁对象(delete pointer;)时,可能会出现问题。

答案 1 :(得分:0)

根据Qt文件

  

当控件返回到事件循环时,将删除该对象。如果   调用此函数时事件循环未运行(例如   deleteLater()之前在对象上调用QCoreApplication::exec(),   一旦启动事件循环,将删除该对象。 如果   主事件循环停止后调用deleteLater()   对象不会被删除。从Qt 4.8起,如果调用deleteLater()   在一个没有运行事件循环的线程中的对象上,   线程完成后,对象将被销毁。

     

请注意,进入和离开新的事件循环(例如,通过打开一个   模态对话框)不会执行延迟删除;对象   要删除,控件必须返回到的事件循环   deleteLater()被召唤了。

     

注意:不止一次调用此函数是安全的;当第一个   递送延迟删除事件,任何待处理事件   对象将从事件队列中删除。

Qt::QueuedConnection类型中deleteLater()将等待完成thread.but在Qt::DirectConnection当有人直接删除对象时,它可能会使应用程序崩溃。 在这种情况下,您需要在删除之前检查线程是否正在运行。