Search Unity

Do UnityEvents automatically remove all listeners when an object is destroyed?

Discussion in 'UGUI & TextMesh Pro' started by any_user, Oct 24, 2014.

  1. any_user

    any_user

    Joined:
    Oct 19, 2008
    Posts:
    374
    I'm used to remove all event listeners from C# events in OnDestroy, but I'm asking myself if this is still needed when using UnityEvents (added by code) – is it? Otherwise what's the best practice? To call RemoveAllListeners() in OnDestroy, I guess?
     
    honor0102 likes this.
  2. secondbreakfast

    secondbreakfast

    Joined:
    Jan 5, 2013
    Posts:
    98
    I think it's a good assumption that if you add the listener through code you should remove the listener through code
     
    Circool likes this.
  3. any_user

    any_user

    Joined:
    Oct 19, 2008
    Posts:
    374
    I normally do it, but in some cases (throwaway objects) it would be handy to just write an anonymous function (I'm just trying to write less code if possible).

    For example when I Instantiate a particle effect prefab which destroys itself: If I want to do something in the instantiating when it's finished, it would be possible to just add an inline anonymous event listener – but only if I know that all event listeners are anyway removed after this object is destroyed.
     
  4. alestane

    alestane

    Joined:
    Sep 26, 2014
    Posts:
    13
    Given that C# is garbage-collected, once an object with events is no longer referenced, its MulticastDelegates will also become collectable.
     
  5. Mistale

    Mistale

    Joined:
    Apr 18, 2012
    Posts:
    173
    ...but seeing that you create a new scope when setting up an anonymous delegate, and that the event handler has a reference to the delegate, won't that prevent the actual object (and the delegate) from being garbage collected until all references are gone?

    We've certainly had these kinds of problems in the past whenever we've forgotten to remove a listener in OnDestroy() (custom eventhandlers).

    The component that was holding the actual delegate implementation would not be collected, and would outlive the actual gameobject that it was attached to, receiving events after it should be gone.

    Just try to add an anonymous method as listener, manually destroy the gameobject and check if your delegate still receives the event it's listening to.
     
  6. any_user

    any_user

    Joined:
    Oct 19, 2008
    Posts:
    374
    Ok I tested this case: The delegate still receives the event, when the receiving object (the one that contains the anonymous delegate) is destroyed. So far it works the same way with UnityEvents like with C# events.

    But I still don't understand if in the other case, when the sending object is destroyed, the anonymous listener blocks the sending object from being garbage collected. This was my initial question (which wasn't very clear I guess).

    Actually, I was asking this question because somewhere was mentioned (in the release notes?), that the UnityEvents fix some common pitfalls of C# events, and I wasn't sure what that meant.
     
  7. alestane

    alestane

    Joined:
    Sep 26, 2014
    Posts:
    13
    Targets retain the listeners that monitor them. Listeners do not retain the targets that they monitor.
     
    noio likes this.
  8. kvfreedom

    kvfreedom

    Joined:
    Mar 30, 2015
    Posts:
    37
    I am also troubled by this problem.I hope it's automatically remove.
     
  9. ookk47oo

    ookk47oo

    Joined:
    Mar 17, 2017
    Posts:
    80
    I'm confused why the Button Class doesn't call RemoveAllListener in its own OnDestroy function
     
    Derptastic and chadfranklin47 like this.
  10. Achie1

    Achie1

    Joined:
    Jan 14, 2018
    Posts:
    26
    Did you find answer to this question? I am interested in this topic too. Thanks