I have a class, which inherits from ValueTree::Listener. In the constructor I call addListener(this) to some external ValueTree.
Do I need to manually call removeListener(this) in the destructor or
does a ValueTree::Listener, call removeListener() when it is deleted automatically/anyway?
Pretty sure you’re expected to call removeListener(this) yourself. Nothing that I can see calls that for you.
You must use
removeListener as matched pairs. So, each time you use an
addListener, you should automatically add it’s corresponding
removeListener to your destructor. Failure to do so will result in crashes.
note that if your valueTree is a class member (copy constructed from the “external ValueTree”) then you don’t need to call removeListener() on it, because your valuetree is going to be destroyed anyway.
Thanks! Not calling removeListener() was a big problem in my VST, it took me quite a while to realise, because I was not having trouble with it, when running it as a standalone…
I added remove Listeners for all ValueTree::Listeners, AudioProcessorValueTree::Listeners, Value::Listeners and Parameter::Listeners and now everything works like a charm.
- It would be nice, to have an explicit note in the documentation of addListener()
- Maybe it could be great, to have removeListener() being called automatically in the Listeners deconstructor implementation, in case it was not already removed by the programmer? Because for now, I need to keep all references to trees, values and parameters only to call removeListener() at the very end.
Anyway, thank you, I am happy it works now!
The reason it is not removing automatically is, that the Listener is just an interface. To automatically remove a listener, it would need a pointer/reference to the thing it listens to.
Then a listener can (and often does) listen to several objects, so it’s not only a pointer/reference, but a list (or rather vector) of pointers.
An alternative approach would be, if the ListenerList would consist of WeakReferences instead of pointers. That way on each call it could check if the listener still exists. But that is overhead, that might be performance critical, nobody knows.
The JUCE way is not to add autmatic behaviour for cases, that might not apply. This follows the overall C++ paradigm only to do things unasked, that don’t add a runtime cost.