The bind() function registers change listeners on ...
# tornadofx
c
The bind() function registers change listeners on the Observable which is the bind target. The Observable has a reference to the underlying list. For example, bind() to an FXCollections.observableArrayList() might be based on a java.util.Collections list. Memory leaks can definitely be a concern with listeners. It's in the documentation. So, you should be using WeakInvalidationListener to provide a way for the JVM to resolve conflicts where there is a bi-directional relationship. "Weak" flags one side to give way to the conflict. It's standard in languages like Objective-C. bind() isn't a concern if the binding is going to persist for the life of the app. Where is might be an issue if you are binding from one temporary window to objects in another temporary window bi-directionally such as trying to keep the two in sync. In these cases, you roll-your-own binding by adding a change listener that will explicitly be removed or automatically removed with a WeakInvalidationListener. You might find this post of interest on the topic. http://bekwam.blogspot.com/2015/08/invalidationlistener-not-called.html
r
If you are using the same invalidation listener on multiple properties, is it better to give each one it's own weak wrapper, or create a single one and have them all use it? i.e.
Copy code
val dirty = InvalidationListener { ... }
init {
    source.xScaleProperty.addListener(WeakInvalidationListener(dirty))
    source.yScaleProperty.addListener(WeakInvalidationListener(dirty))
}
vs
Copy code
val dirty = InvalidationListener { ... }
init {
    val weak = WeakInvalidationListener(dirty)
    source.xScaleProperty.addListener(weak
    source.yScaleProperty.addListener(weak)
}
c
In my post, you'll see that the first one actually reclaimed the listeners immediately.
r
Sorry, I'm assuming
dirty
is an
InvalidationListener
stored as a member so it won't get reclaimed. My question was if there is a downside to just using a single weak reference to the listener. I'll update my example to make it clearer. Updated
c
as a class member...that'll work
i was surprised when i found that and maybe it's not an issue anymore
h
@carlw I was referring to this problematic code
children.bind(myController.list.sorted(sortOuter())) { element ->
from my example on friday. sorted() returns a SortedList, which will only survive in the scope of the bind function. As the bind function doesn't keep a reference of what it binds to, the garbage collector comes cleaning it up.