簡體   English   中英

在MonoBehaviour中注銷事件處理程序

[英]Unregister event handler in MonoBehaviour

我在從MonoBehaviour繼承的類中的Start方法中注冊了一個事件處理程序(委托)。 我想在這種情況下防止內存泄漏。

public class CharactersController: MonoBehaviour
{
    void Start()
    {
        npc.CollisionEntered += OnNpcCollisionEnter;
    }
}

什么是注銷委托的正確或最佳方法? 有一種方法OnDestroy http://docs.unity3d.com/ScriptReference/MonoBehaviour.OnDestroy.html

醫生說

當MonoBehaviour被銷毀時,將調用此函數。

僅在以前處於活動狀態的游戲對象上調用OnDestroy。

但是尚不清楚何時會破壞MonoBehaviour,以及如果先前未激活游戲對象會怎樣。

OnEnable中注冊事件,然后在OnDisable中注銷事件是適當的。

除非啟用了行為,否則不會調用Start()方法 而且只有在其所在的游戲對象被激活時才能啟用。 因此,您可以放心地假設,如果該行為被調用了OnDestroy() ,則它確實早先獲得了對Start()的調用。

單聲道行為的破壞發生在同一幀內(渲染之前) 但是,如果您不只是因為預防內存泄漏而問這個問題,而是您的邏輯依賴於此,那肯定是有問題的。

正如@Programmer正確指出的那樣,您的代碼很可能應該訂閱和取消訂閱OnEnabledOnDisabled事件。 這更好地遵循了組件設計模式的概念:畢竟,該模式假設(並且在邏輯上如此)假定組件僅在由外部系統故意激活時才起作用,而在禁用時才返回睡眠狀態。 現在,Unity開發人員不得不在很多地方略微修改這些准則,因為在C#代碼方面,MonoBehaviours幾乎是他們擁有的唯一切入點,但是仍然最好遵循系統的隱式規則。

最后,老實說,由於內存泄漏,我從未在Unity項目中看到過明顯的性能問題。 考慮一下這是件好事,但是如果通過將對象移動到對象池中而完全消除了對象的實例化和銷毀,則可以花費更多的時間,因為它們經常是對象的來源。問題。

如果您僅在Start上注冊一個處理程序,並且CharactersController可以延長應用程序的生命周期,那么您就不會泄漏內存。 如果您在對象生存期內的某個重復發生的事件中注冊處理程序,然后又不注銷它,則泄漏的可能性更大。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM