【问题标题】:Problem with event unsubscribing OnDisable事件取消订阅 OnDisable 的问题
【发布时间】:2023-03-18 03:31:01
【问题描述】:

我在 OnEnable 中注册事件并在 OnDisable 中取消注册它们。在大多数情况下它可以工作,但我有一个简单的脚本,当我加载新场景并通过按下按钮调用事件时,它会导致 MissingReferenceException: The object of type 'GraphicsSwitch' has been destroyed but you are still trying to access it.

我知道在使用 Debug.Log 检查时调用了 OnDisable。在新场景中按下按钮之前,不会在新场景中调用该事件。

添加if (this != null) 后,错误消失了。检查 gameObject 是否为 null 不起作用。似乎该事件没有取消订阅,并且该方法是在前一个场景中的销毁对象上调用的。

代码很简单:

private void OnEnable()
{
    AdjustGraphics();
    GameSettings.GraphicsChanged += AdjustGraphics;
}

private void OnDisable()
{
    GameSettings.GraphicsChanged -= AdjustGraphics;
}

private void AdjustGraphics()
{
    //without this line I get the error
    if (this != null)
        gameObject.SetActive(GameSettings.Graphics >= requiredQuality);
}

不应在新加载的场景中调用方法 AdjustGraphics。我认为这些对象应该立即取消订阅。 在取消订阅活动时我错过了什么?

我知道 Unity 中的对象不会立即销毁,但 OnDisable 会按时调用,因此我的脚本/对象在加载新场景时不应再监听 GameSettings.GraphicsChanged 事件。

【问题讨论】:

  • 这表明它以某种方式订阅了不止一次。
  • 你可以试试 if(GameSettings != null) GameSettings.GraphicsChanged -= AdjustGraphics;
  • 在执行+= 之前,您还应该始终执行-=。即使之前没有添加回调也是允许的,并确保它总是只添加一次。
  • 谢谢大家,@derHugo 谢谢你的好建议。不知道这是允许的。
  • 我仍然在 += 之前得到 -= 的异常。我检查了所有参考资料,此代码是我订阅或取消订阅的唯一地方。我有另一个具有相同方法名称的脚本,但这不应该是问题吗?

标签: c# unity3d events


【解决方案1】:

如果我错了,请纠正我,但是当您加载新场景时,您的对象会被破坏,因此 MissingReferenceException 除非您使用 DontDestroyOnLoad

如果您不想使用它,请确保在场景加载开始时初始化对象,即在调用其任何函数之前确保您的对象存在于场景中。

【讨论】:

  • 新场景加载时对象被销毁,这就是您需要取消订阅的原因。这不是我要问的。不是我的反对票;)
猜你喜欢
  • 1970-01-01
  • 2018-01-05
  • 2013-05-18
  • 1970-01-01
  • 2017-04-25
  • 1970-01-01
  • 2020-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多