为了账号安全,请及时绑定邮箱和手机立即绑定

关于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。事件系统将继续对已删除的对象->崩溃进行操作。

由于回溯通常看起来很奇怪(就像访问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 关注
  • 1640 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信