【问题标题】:Ambiguous destructor for QObject?QObject的模棱两可的析构函数?
【发布时间】:2015-08-18 18:27:46
【问题描述】:

QObject 析构函数的 Qt 参考说:

所有进出对象的信号都会自动断开,并且对象的任何未决已发布事件都将从事件队列中删除。但是,使用 deleteLater() 通常比删除更安全直接一个 QObject 子类。

...

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

请注意上面部分中的粗线。

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

【问题讨论】:

    标签: qt destructor qobject


    【解决方案1】:

    警告:在挂起的事件等待交付时删除 QObject 可能会导致崩溃。 如果 QObject 存在于与当前执行的线程不同的线程中,则不能直接删除它。

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

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

    如果您要删除的对象正在从中删除它的线程中运行,那么是的,该对象的所有未决已发布事件都将从事件队列中删除。

    让我们想想发生了什么。

    当一个对象调用一个信号时,如果对象的接收者与被调用者在同一个线程中,则立即调用该函数(假设connection type是Automatic,或者Direct)。

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

    在删除对象时,如果我们从不同的线程调用 delete,它无法访问其他线程的事件队列来删除未决事件。更重要的是,它不是线程安全的,可能会导致崩溃。

    【讨论】:

    • 谢谢@TheDarkKnight。让我们稍微改一下这个问题:如果 QObject 只存在于一个线程中,那么调用 delete 是否安全,就像调用 deleteLater 一样安全?
    • 这取决于代码中删除对象的位置。如果代码在槽函数中,则you should call deleteLater
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-21
    • 2019-09-10
    • 1970-01-01
    • 1970-01-01
    • 2015-05-10
    相关资源
    最近更新 更多