If i assign the listener to a file level variable ...
# coroutines
m
If i assign the listener to a file level variable outside the method, and clear it inside awaitClose, it does work
s
I think it is because the compiler optimizes the
listener
variable out. It just assigns the listener as the argument to the
start
method. This means the
Listener
instance reference goes out of scope. The
start
only keeps a weak-reference. Which means that no-one is keeping a hard reference anymore and it gets gc-ed
m
even in debug builds. hm. it may be that. any workaround ?
s
BTW: I don’t like APIs at all that keep weak-references to callbacks and listeners. And what you experience is one of the reasons.
1
m
yes, but i cannot change the API. That was my initial proposal
s
awaitClose { listener = null }
may work?
m
to try it out, i keeped a static reference. It worked. Maybe a reference inside the callback will work as well. will try. thanks
s
I don’t think that will get optimized out and will keep the reference to the
Listener
instance through the
listener
variable, until `awaitClose`’s lambda is called
m
it’s hard to reproduce, since i must run it in a loop and hope the GC kicks in in the middle. I didnt found any other way
s
Be careful using static/global vars like that… you may introduce leaks if you are not careful.
Did you try
awaitClose { listener = null }
?
m
yes i know. That was just to test my theory about the GC. I didnt knew the cause
t
Some listener APIs may only keep weak references to the listener object, hence GC clears it when it is no longer referenced. That's the case with Android's
SharedPreferences.OnPreferenceChangeListener
I think
l
You should unregister your listener in the awaitClose lambda anyway (or you create a leak for cases where the reference behind is a regular one). By doing so, that problem will go away.
m
yes, except the api has no way of unregistering
l
Ah, what a bad API…
Anton solution should work
m
yes, it was compiler optimization in the end. i got it thanks
l
It's a recent one, it was introduced in 1.4.20