亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

關于Qt中的信號和插槽,delete和deleteLater如何工作?

關于Qt中的信號和插槽,delete和deleteLater如何工作?

素胚勾勒不出你 2019-12-26 10:17:45
有一個QNetworkReply類的對象。有一個插槽(在其他對象中)連接至其finish()信號。信號是同步的(默認信號)。只有一個線程。在某個時刻,我想擺脫兩個對象。沒有更多信號或來自它們的任何東西。我希望他們走了。好吧,我想,我會用delete obj1; delete obj2;但是我真的可以嗎??QObject的規范說:在等待事件發送時刪除QObject可能導致崩潰。什么是“待處理事件”?這是否意味著在我打電話給我時delete,已經有一些“待處理事件”要傳遞,并且它們可能會導致崩潰,而我真的無法檢查是否有任何事件?假設我打電話給:obj1->deleteLater(); obj2->deleteLater();為了安全。但是,我真的很安全嗎?該deleteLater補充說,將在主回路控制時到達那里進行處理的事件。是否可以存在obj1或obj2已經存在一些未決事件(信號),在處理deleteLater 之前在主循環中等待處理?那將是非常不幸的。我不想編寫代碼來檢查“某種程度上已刪除”狀態,而忽略所有插槽中的傳入信號。
查看完整描述

3 回答

?
翻閱古今

TA貢獻1780條經驗 獲得超5個贊

如果遵循以下兩個基本規則,則刪除QObject通常是安全的(即,在正常實踐中;可能是我不了解atm的病理情況):

  • 切勿刪除插槽(或方法)中的對象,該插槽或方法被(同步,連接類型“直接”)信號直接或間接從要刪除的對象中調用。例如,如果您有一個帶有信號Operation :: finished()和插槽Manager :: operationFinished()的類Operation,則不想刪除在該插槽中發出信號的操作對象。發出finished()信號的方法可能會在發出之后繼續訪問“ this”(例如訪問成員),然后對無效的“ this”指針進行操作。

  • 同樣,切勿刪除從對象的事件處理程序中同步調用的代碼中的對象。例如,請勿在其SomeWidget :: fooEvent()或從此處調用的方法/插槽中刪除SomeWidget。事件系統將繼續對已刪除的對象->崩潰進行操作。

由于回溯通??雌饋砗芷婀郑ň拖裨L問POD成員變量時崩潰一樣),尤其是當您具有復雜的信號/插槽鏈(其中刪除可能會發生幾步下降,最初是由信號或事件發起的)時,兩者都很難追蹤。被刪除的對象。

這種情況是deleteLater()的最常見用例。它確保當前事件可以在控件返回到事件循環之前完成,事件循環然后刪除該對象。我發現,另一個更好的方法通常是使用排隊的連接/ QMetaObject :: invokeMethod(...,Qt :: QueuedConnection)延遲整個操作。


查看完整回答
反對 回復 2019-12-26
?
吃雞游戲

TA貢獻1829條經驗 獲得超7個贊

您推薦的文檔的后兩行給出了答案。


從?QObject,


在等待事件發送時刪除QObject可能導致崩潰。如果QObject與當前正在執行的線程不在同一線程中,則不能直接刪除它。使用deleteLater()代替,這將導致事件循環在所有未決事件傳遞到對象后刪除該對象。


它明確表示我們不要從其他線程中刪除。由于您只有一個線程應用程序,因此刪除是安全的QObject。


否則,如果您必須在多線程環境deleteLater()中將其刪除,請使用它將QObject在處理完所有事件后將其刪除。


查看完整回答
反對 回復 2019-12-26
?
慕桂英546537

TA貢獻1848條經驗 獲得超10個贊

您可以閱讀有關以下內容之一的Delta對象規則來找到問題的答案:


信號安全(SS)。

從一個對象的信號之一調用的插槽中調用對象(包括析構函數)上的方法必須是安全的。


分段:


QObject的核心是支持在發信號時刪除。為了利用它,您只需確保您的對象在刪除后不嘗試訪問其自己的成員。但是,大多數Qt對象不是以這種方式編寫的,也不要求它們兩者都存在。因此,如果需要在對象的信號之一期間刪除對象,建議始終調用deleteLater(),因為“刪除”可能會使應用程序崩潰。


不幸的是,何時使用“ delete”和deleteLater()并不總是很清楚。也就是說,代碼路徑具有信號源并不總是很明顯。通常,您可能會有一段代碼在今天安全的某些對象上使用“刪除”,但是在將來的某個時候,同一代碼塊最終會從信號源中被調用,現在您的應用程序突然崩潰了。解決此問題的唯一通用方法是始終使用deleteLater(),即使乍一看似乎沒有必要。


通常,我認為Delta對象規則是每個Qt開發人員必須閱讀的內容。這是極好的閱讀材料。


查看完整回答
反對 回復 2019-12-26
  • 3 回答
  • 0 關注
  • 1950 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號