3 回答

TA貢獻1780條經驗 獲得超5個贊
如果遵循以下兩個基本規則,則刪除QObject通常是安全的(即,在正常實踐中;可能是我不了解atm的病理情況):
切勿刪除插槽(或方法)中的對象,該插槽或方法被(同步,連接類型“直接”)信號直接或間接從要刪除的對象中調用。例如,如果您有一個帶有信號Operation :: finished()和插槽Manager :: operationFinished()的類Operation,則不想刪除在該插槽中發出信號的操作對象。發出finished()信號的方法可能會在發出之后繼續訪問“ this”(例如訪問成員),然后對無效的“ this”指針進行操作。
同樣,切勿刪除從對象的事件處理程序中同步調用的代碼中的對象。例如,請勿在其SomeWidget :: fooEvent()或從此處調用的方法/插槽中刪除SomeWidget。事件系統將繼續對已刪除的對象->崩潰進行操作。
由于回溯通??雌饋砗芷婀郑ň拖裨L問POD成員變量時崩潰一樣),尤其是當您具有復雜的信號/插槽鏈(其中刪除可能會發生幾步下降,最初是由信號或事件發起的)時,兩者都很難追蹤。被刪除的對象。
這種情況是deleteLater()的最常見用例。它確保當前事件可以在控件返回到事件循環之前完成,事件循環然后刪除該對象。我發現,另一個更好的方法通常是使用排隊的連接/ QMetaObject :: invokeMethod(...,Qt :: QueuedConnection)延遲整個操作。

TA貢獻1829條經驗 獲得超7個贊
您推薦的文檔的后兩行給出了答案。
從?QObject,
在等待事件發送時刪除QObject可能導致崩潰。如果QObject與當前正在執行的線程不在同一線程中,則不能直接刪除它。使用deleteLater()代替,這將導致事件循環在所有未決事件傳遞到對象后刪除該對象。
它明確表示我們不要從其他線程中刪除。由于您只有一個線程應用程序,因此刪除是安全的QObject。
否則,如果您必須在多線程環境deleteLater()中將其刪除,請使用它將QObject在處理完所有事件后將其刪除。

TA貢獻1848條經驗 獲得超10個贊
您可以閱讀有關以下內容之一的Delta對象規則來找到問題的答案:
信號安全(SS)。
從一個對象的信號之一調用的插槽中調用對象(包括析構函數)上的方法必須是安全的。
分段:
QObject的核心是支持在發信號時刪除。為了利用它,您只需確保您的對象在刪除后不嘗試訪問其自己的成員。但是,大多數Qt對象不是以這種方式編寫的,也不要求它們兩者都存在。因此,如果需要在對象的信號之一期間刪除對象,建議始終調用deleteLater(),因為“刪除”可能會使應用程序崩潰。
不幸的是,何時使用“ delete”和deleteLater()并不總是很清楚。也就是說,代碼路徑具有信號源并不總是很明顯。通常,您可能會有一段代碼在今天安全的某些對象上使用“刪除”,但是在將來的某個時候,同一代碼塊最終會從信號源中被調用,現在您的應用程序突然崩潰了。解決此問題的唯一通用方法是始終使用deleteLater(),即使乍一看似乎沒有必要。
通常,我認為Delta對象規則是每個Qt開發人員必須閱讀的內容。這是極好的閱讀材料。
- 3 回答
- 0 關注
- 1950 瀏覽
添加回答
舉報