2015-06-04 88 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