2015-06-04 49 views
3

Qt的参考表示:QObject的模糊析构函数?为QObject的析构函数

所有信号并从该对象被自动断开,并且为对象任何未决发布事件从事件队列中删除。但是,使用deleteLater()而不是直接删除QObject子类通常更安全。

...

警告:删除一个QObject而未决的活动等待交付可以导致崩溃。如果QObject存在于与当前正在执行的线程不同的线程中,则不能直接删除它。使用deleteLater()代替,这将导致事件循环在所有未处理事件传递给它之后删除对象。

注意上面部分的粗线。

所以问题是:未决的发布事件是否从事件队列中删除?

回答

4

警告:正在等待传递待处理事件时删除QObject可能导致崩溃。如果它存在于当前正在执行的另一个线程中,则不能直接删除该QObject

您专注于该句子的第一个陈述,而忽略了第二个陈述。这种情况涉及删除存在于不同线程中的对象 - (与其他thread affinity不同)。

例如,如果您正在主线程(GUI)上运行并且在第二个线程中有一个对象,则从主线程中删除另一个对象可能会导致崩溃。

如果您要删除的对象正在从其中删除的线程中运行,则是,则该对象的任何挂起的已发布事件将从事件队列中删除。

让我们思考一下发生了什么。

当对象调用信号时,如果对象的接收者与被调用者位于同一线程中,则立即调用该函数(假设connection type为自动或直接)。

如果对象的接收者具有不同的线程关联性,则自动连接将导致Queued-Connection;不是直接调用函数,而是将事件发布到接收对象的线程的事件队列中。

当涉及到删除对象时,如果我们从另一个线程调用删除,它将无法访问其他线程的事件队列以删除未决事件。更重要的是,它不是线程安全的并可能导致崩溃。

+0

谢谢,@TheDarkKnight。让我们稍微改写一下这个问题:如果QObject仅存在于一个线程中,那么调用delete可以安全地调用deleteLater吗? – agnor

+2

这取决于您要删除对象的代码中的点。如果代码位于槽功能中,那么[你应该调用deleteLater](http://stackoverflow.com/questions/22376298/when-to-use-deletelater/22378104#22378104) – TheDarkKnight