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

Zenject中ITickable绑定为Transient时Tick()不调用的解决方法

Zenject中Transient模式下ITickable实例的Tick方法不执行的解决方案

问题原因

Zenject的ITickable更新机制默认只会自动追踪**单例(Singleton)**实例:容器会持有单例的唯一引用,并自动将其加入Tick循环队列。而当使用AsTransient()绑定ITickable实现类时,每次注入都会创建新实例,容器不会保留这些实例的引用,因此不会自动将它们注册到Tick系统中,导致Tick()方法无法被调用。

解决方案

方案1:在Timer类内部手动注册/注销Tickable

通过在Timer的构造函数中注入ITickableManager,手动将自身注册到Tick队列,同时实现IDisposable来处理注销,避免内存泄漏:

using Zenject;

public class Timer : ITickable, IDisposable
{
    private readonly ITickableManager _tickableManager;

    public Timer(ITickableManager tickableManager)
    {
        _tickableManager = tickableManager;
        // 注册到Tick循环
        _tickableManager.AddTickable(this);
    }

    public void Tick()
    {
        // 编写你的每帧执行逻辑
    }

    public void Dispose()
    {
        // 从Tick循环中移除,避免内存泄漏
        _tickableManager.RemoveTickable(this);
    }
}

绑定方式保持不变:

Container.BindInterfacesAndSelfTo<Timer>().AsTransient();

注意:当Timer实例不再被使用时,务必调用Dispose()方法(比如在依赖该Timer的对象销毁时)。

方案2:通过绑定回调自动注册/注销

无需修改Timer类,在绑定配置中通过OnInstantiated和OnDestroyed回调完成Tickable的注册与注销:

using Zenject;

Container.BindInterfacesAndSelfTo<Timer>()
    .AsTransient()
    .OnInstantiated<Timer>((context, timer) =>
    {
        // 实例创建后注册到Tick循环
        var tickableManager = context.Container.Resolve<ITickableManager>();
        tickableManager.AddTickable(timer);
    })
    .OnDestroyed<Timer>((context, timer) =>
    {
        // 实例销毁时从Tick循环移除
        var tickableManager = context.Container.Resolve<ITickableManager>();
        tickableManager.RemoveTickable(timer);
    });

这种方式将Tickable的管理逻辑集中在绑定配置中,保持Timer类的职责单一。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 19:44:58