I’m assuming that every time I open the settings and this script becomes ‘Active’, another Listener get’s piled up. But I could be wrong. I’m hoping I don’t have garbage collecting in my scripts. =P
Anyway, if both the button and the subscriber are leaving the scene/being destroed at the same time (such as a scene being unloaded or exiting playmode), then it shouldn’t be a problem.
If the subscriber is leaving/destroyed while the button remains, then it should unsubscribe, same as with any delegate.
The UI page gets hidden and unhidden (active, inactive) as needed while navigating the UI.
Each time it is ‘awake’ it adds the listeners.
I just wanted to make sure they aren’t sticking around and piling up.
So I thought maybe it would look something like this:
If you keep adding listeners without removing them, yes I believe they will continue to pile up causing unexpected behaviour.
Like any delegate you need to unsubscribe when needed, otherwise you’ll get unexpected behaviour, or null-reference errors if the listener no longer exists.
Awesome, then I think I will add the code in OnDisable() as I wrote above.
Only thing I will change is:
Instead of adding the listeners on Awake(), I’ll be adding them OnEnable().
So my final result looks like this:
That’s the pattern I use, never had any issues with it: OnEnable / OnDisable is solid for MonoBehaviours.
I think it’s just Good Practice™ doing the remove as well: you never know if years down the line you’ll change the behaviour or lifecycle slightly and violate your “add once” assumptions.
As a rule, I would avoid using RemoveAllListeners when in effect you are trying to remove one listener. This is a good way for obfuscated bugs to occur. Instead, I’d format this using methods that I can directly put into the appropriate method:
I just like to add. OnEnable and OnDisable are the respective counterparts as it was already established in this thread. The counterpart of Awake is OnDestroy. So don’t mix them up OnEnable / OnDisable are called every time the gameobject / component changes its activated / enabled state. Awake and OnDestroy are one time events in the lifetime of the object. Awake will only be called once and so is OnDestroy. So things done in Awake that needs to be “undone” have to be reverted in OnDestroy. Though, especially when it comes to event subscriptions using OnEnable / OnDisable usually makes more sense as in 99% of all cases you would expect a component to not react to events when you disable it. Though there are always exceptions of course