Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Resolved Do i need to unsubscribe my event listeners?

Discussion in 'Scripting' started by Magnesium, Apr 13, 2021.

  1. Magnesium

    Magnesium

    Joined:
    Sep 14, 2014
    Posts:
    179
    Hello,

    Code (CSharp):
    1. myGameObject.GetUpdateEvent().AddListener(MyUpdate);
    I usually work with the TypeScript Angular framework and since a few versions, it takes care of removing event listeners on destroyed components.

    Does Unity require to do it manually?

    Thanks
     
  2. Lekret

    Lekret

    Joined:
    Sep 10, 2020
    Posts:
    367
    Usually yes, AFAIK if GameObject is destroyed, but you didn't unsubscribe from event, then this event will have reference to subscribed object and GC wouldn't be able to remove it, i.e. this will be a memory leak.
    Also unsubscription makes sense in context of Unity, all of your Awake/Start/Update functions don't work on disabled scripts or on disabled GameObjects, all unity components don't work as well, so it makes sense to subscribe in OnEnable and unsubscribe in OnDisabled to make disabled objects purely disabled.
     
    Last edited: Apr 13, 2021
  3. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    For plain C# events, yes, you need to manually unsubscribe.

    For UnityEvents, I believe you don't have to, and it's taken care of automatically.
    Someone correct me if I'm wrong on that.
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,561
    It depends on which object you're talking about.

    Basically an event system is the observer pattern (with a different interface). So you have an observer (the thing that is listening for an event), and the subject (the thing that has an event).

    When you register an event handler with the subject, the subject now has a reference to the observer (it's a delegate, but the delegate has a reference to the observer since it's needed to call the method in question).

    This means if the observer is destroyed there is a reference still out there in the wild pointing at it which keeps the GC from cleaning it up. So when an objserver is destroyed it should unregister all event handlers. (note that static event handlers don't matter here since there is no instanced object to reference back to).

    Vice versa doesn't actually need unregistering since the observer doesn't actually maintain any reference to the subject (unless you explicitly did so with some variable... in which case you just need to set that variable null).

    That all goes for C# events/delegates.

    When it comes to UnityEvent things get a bit more complicated.

    There are 2 ways to register with a UnityEvent. There are "persistent callbacks" and regular old listeners. The persistent ones are the callbacks you register through the inspector, and regular ones are done through 'AddListener'.

    AddListener approach really just is a delegate so really the rules that are applied to C# events are the same. Observer's need to unregister themselves when destroyed otherwise the subject will hold a ref to them.

    The persistent though... :shrug: on the specifics. You can sift through the source code to try and glean the specifics:
    https://github.com/Unity-Technologi.../Runtime/Export/UnityEvent/UnityEvent.cs#L760

    But it has all sorts of fun stuff going on in it. At first glance it appears like it would hold a reference, but there might be some unity engine side stuff that cleans it up. Could run some tests to find out... but I'm at work right now. Maybe later today when I have a longer break.
     
    Magnesium likes this.
  5. Magnesium

    Magnesium

    Joined:
    Sep 14, 2014
    Posts:
    179
    Thanks, that's really helpful. I havn't dug into persistent event, i've only used UnityEvents so far.
     
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,561
    Persistent callbacks are part of UnityEvent:
    https://github.com/Unity-Technologi.../Runtime/Export/UnityEvent/UnityEvent.cs#L379

    It's the serializable class that facilitates registering callbacks through the inspector on a UnityEvent.

    If you've used UnityEvent and dragged something via the inspector onto said UnityEvent... you used persistent callbacks.
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,020
    I always try to subscribe and unsubscribe with OnEnable() and OnDisable() and it has never let me down.
     
    Lekret likes this.
  8. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,561
    It is always best to unsubscribe if you're not certain if you should. It can't hurt.