You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

断开SceneTreeTimer后为何未显示为已删除对象?

手动触发SceneTreeTimer的timeout信号后,为何定时器对象未被标记为[Deleted Object]?

我尝试断开SceneTreeTimer的信号,避免其超时后调用指定函数,代码实现如下:

extends Node2D

onready var something = $Node2D
var timer

func abort():
    timer.disconnect("timeout",something,"queue_free")
    timer.emit_signal("timeout")
    
    print("timer=",timer)

func _ready():
    timer=get_tree().create_timer(3)
    timer.connect("timeout",something,"queue_free")
    
    ...

    abort()

虽然操作阻止了定时器调用目标函数,但执行abort()后打印timer,结果显示为timer=>[SceneTreeTimer:1276]。按逻辑,定时器时间已过应该显示为[Deleted Object],这是为什么?


这是因为SceneTreeTimer的自动销毁逻辑只在自然超时时才会触发,手动调用emit_signal("timeout")仅仅是触发了信号事件,并不会触发SceneTree对定时器的销毁流程。

具体拆解你的代码流程:

  • 在_ready中创建了一个3秒的定时器,同时连接了timeout信号到something的queue_free方法
  • 你立刻调用了abort(),此时定时器还没走到设定的3秒计时终点,自然超时的逻辑根本没触发
  • 断开信号只是切断了目标函数的调用链路,但定时器本身的生命周期完全不受影响;手动触发timeout信号也只是模拟了超时的信号触发,并没有启动SceneTree内置的定时器销毁机制

另外补充一点:就算等定时器自然超时,它也不会立刻变成[Deleted Object]——SceneTree会在当前帧的逻辑处理结束后,才会清理掉已经完成计时的定时器对象。你手动触发信号的操作完全绕开了这套自动销毁流程,所以定时器对象依然保持有效引用,打印出来就是正常的对象实例,而非已删除标记。

如果想要主动销毁定时器,可以调用timer.stop(),这会让SceneTree清理掉这个定时器对象,之后再打印就会看到[Deleted Object]了。

内容的提问来源于stack exchange,提问作者cak3_lover

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 22:45:30