在哪里可以统一跟踪订阅的事件?

问题描述 投票:0回答:1

我有一个小型事件处理程序,它在 Start 方法中订阅来自不同对象的许多事件,还有一个 OnDestroy 方法,它取消订阅脚本在 Start 方法中订阅的所有事件。

private void Start()
{
    _winPanelController.OnGiveAwards += CalculateCoins;
    _revivePaymentManager.OnUpdatedBalance += SaveBalanceToJSON;
    _revivePaymentManager.OnPayingFinished += RespawnAllEnemies;
    _revivePaymentManager.OnPayingFinished += RevivePlayer;
    _revivePaymentManager.OnPayingNotFinished += InformPlayerNotEnoughGems;
    _actorUI.OnPlayerStop += SetPlayerMovement;
    _wavesController.OnWin += ActivationWinPanel;
    _wavesController.OnStoppedWave += StopSpawningForAllSpawners;
    _wavesController.OnEnemyLevelUp += SetNewLevelForEnemies;
    _player.OnDead += EnableRevivePanel;
    _player.OnRevived += RespawnAllEnemies;

    foreach (var spawner in _enemySpawner)
    {
        spawner.OnXPCollected += CalculateCollectedXP;
        spawner.OnDamageCollected += CalculateCollectedDamage;
    }
}

private void OnDestroy()
{
    _winPanelController.OnGiveAwards -= CalculateCoins;
    _revivePaymentManager.OnUpdatedBalance -= SaveBalanceToJSON;
    _revivePaymentManager.OnPayingFinished -= RespawnAllEnemies;
    _revivePaymentManager.OnPayingFinished -= RevivePlayer;
    _revivePaymentManager.OnPayingNotFinished -= InformPlayerNotEnoughGems;
    _wavesController.OnWin -= ActivationWinPanel;
    _wavesController.OnStoppedWave -= StopSpawningForAllSpawners;
    _wavesController.OnEnemyLevelUp -= SetNewLevelForEnemies;
    _player.OnDead -= EnableRevivePanel;
    _player.OnRevived -= RespawnAllEnemies;

    foreach (var spawner in _enemySpawner)
    {
        spawner.OnXPCollected -= CalculateCollectedXP;
        spawner.OnDamageCollected -= CalculateCollectedDamage;
    }
}`

问题是我不明白在哪里可以跟踪我订阅了多少个事件,它们占用了多少 RAM 或 CPU 时间?或者说不可能追踪这个?如果我不取消订阅这些事件会发生什么,我如何跟踪内存泄漏?

我尝试在 Memory Profiler 中查找与事件相关的内容,但也没有找到任何内容。我在Profiler中发现最多的是进程

Update.ScriptsRunBehaviorUpdate > BehaviorUpdate > EventSystem.Update() [Invoke]
。这是 Unity 的标准 EventSystem 吗?

c# unity-game-engine events memory-leaks profiler
1个回答
0
投票

我不明白在哪里可以跟踪我订阅了多少活动

您可以查看this问题的答案。有一些选项可以使用附加的调试器和通过反射来完成此操作。不过,我绝不会建议您在运输构建上使用反射。如果它只是为了您和调试目的,那很好,但它会带来开销,并且可能不适用于所有平台。

它们需要多少 RAM 或 CPU 时间?

很少。它们在内部列表中保存对对象的引用和函数指针。即使您有数百名订阅者,您实际上也不会注意到影响。它基本上是一个循环,迭代所有函数以在其对象上调用它们并传递参数。

或者是不可能追踪这个吗?

请参阅上面我关于调试它们的观点。您完全可以查看内部发生的情况,但如果您真的想跟踪它,您可能应该运行一个内部事件系统,但这也可能会变得混乱。

如果我不取消订阅这些事件会发生什么,我如何跟踪内存泄漏?

这是一个非常好的问题。通常,当一个对象超出范围并被垃圾收集时,事件不会关心它,并且会将其从调用列表中删除。在 Unity 中,当您订阅 Unity 托管对象(从 MonoBehaviour 或 ScriptableObject 继承的对象)时,它们不会从调用列表中删除,并且将在它们上调用事件。我建议取消订阅它们,如果您发现某个不应该存在的对象上有一些奇怪的 NullReferenceException,请确保您已取消订阅您所描述的所有事件。

© www.soinside.com 2019 - 2024. All rights reserved.