在TornadoFX中,我希望取消订阅自定义事件,以便接收者永远不会再次处理不必要的事件,并且可能避免内存泄漏等问题,但是,当我在代码中使用unsubscribe<MyEvent>
方法时,它不会干活了。这是我的代码的一部分:
object MyEventObj: FXEvent(EventBus.RunOn.BackgroundThread)
class MyEventBus(val personlist:List<PersonOld>): FXEvent()
class MyController: Controller()
{
init
{
subscribe<MyEventObj> {
unsubscribe<MyEventObj> {
println("Unsubscribe event!") //unsubscrib event and make sure the next code just runs once, but never works!
}
println("Event has received!")
val items = listOf(PersonOld("Name A", 20), PersonOld("Name B", 25))
fire(MyEventBus(items))
}
}
}
那么,问题是什么?以及如何在TornadoFX中使用unsubscribe
?谢谢你提前帮助我!
答案 0 :(得分:1)
unsubscribe
函数将事件侦听器作为唯一参数。因此,为了能够取消订阅,您需要将侦听器保存为成员val,以便您可以引用它。为了使事情更有趣,你不能在监听器本身内引用this
,所以你需要调用另一个函数才能成功取消订阅。这是一个完整的例子:
object MyEvent : FXEvent()
class MyView : View() {
override val root = stackpane {
paddingAll = 100
button("Fire!") {
setOnAction {
fire(MyEvent)
}
}
}
val myListener: (MyEvent) -> Unit = {
alert(Alert.AlertType.INFORMATION, "Event received!", "This message should only appear once.")
stopListening()
}
init {
subscribe(myListener)
}
fun stopListening() = unsubscribe(myListener)
}
如果可以从内部引用侦听器,我们可以直接在侦听器中添加unsubscribe()
调用,但这是不可能的,至少不是Kotlin 1.0。
编辑:我们刚刚添加了times = n
参数进行订阅,因此您无需自行处理取消注册。默认情况下,每次事件触发时都会触发事件侦听器,但是通过传递1
,您可以在第一次之后自动取消注册。有了这个新功能,进入TornadoFX 1.6.3,您可以简单地执行此操作:
class MyView : View() {
override val root = stackpane {
paddingAll = 100
button("Fire!") {
setOnAction {
fire(MyEvent)
}
}
}
init {
subscribe<MyEvent>(times = 1) {
alert(Alert.AlertType.INFORMATION, "Event received!", "This message should only appear once.")
}
}
}
EDIT2: TornadoFX 1.6.3还将引入触发器操作的EventContext
,因此您可以在下一个事件监听器中执行unsubscribe()
版。然后,您可以替代times
参数:
subscribe<MyEvent> {
alert(Alert.AlertType.INFORMATION, "Event received!", "This message should only appear once.")
unsubscribe()
}