Традиционно, когда что-то подписывается на что-то другое, оно отвечает за отмену подписки. Вы можете сделать это, используя IdentityHashMap:
class WeatherStation {
val temperatureChangedObservers = IdentityHashMap<Any, (Int) -> Unit>()
var temperature: Int by Delegates.observable(0) { _, _, newValue ->
temperatureChangedObservers.values.forEach { it(newValue) }
}
}
// ...
val weatherStation = WeatherStation()
weatherStation.temperatureChanged.add(this) { temperature ->
println("Temperature changed: $temperature")
}
// remove self as observer when going out of scope:
weatherStation.remove(this)
Я использовал IdentityHashMap вместо MutableMap или HashMap, поэтому нам не придется беспокоиться о возможности двух разных наблюдателей, возможно, имеющих объектное равенство.
Если вы хотите автоматизировать отписку от рассылки, чтобы вам не приходилось беспокоиться об этом, когда ваш фрагмент или действие выходит из области видимости, вы можете потребовать, чтобы наблюдатели были LifecycleOwners, чтобы вы могли наблюдать их жизненные циклы. Я не проверял это:
class WeatherStation: LifecycleObserver {
private val temperatureChangedObservers = IdentityHashMap<LifecycleOwner, (Int) -> Unit>()
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onObserverDestroyed(source: LifecycleOwner) {
temperatureChangedObservers.remove(source)
}
fun observeTemperature(observer: LifecycleOwner, action: (Int) -> Unit) {
temperatureChangedObservers[observer] = action
observer.lifecycle.addObserver(this)
}
var temperature: Int by Delegates.observable(0) { _, _, newValue ->
temperatureChangedObservers.values.forEach { it(newValue) }
}
}
// ...
val weatherStation = WeatherStation()
weatherStation.observeTemperature(this) { temperature ->
println("Temperature changed: $temperature")
}