GWT-MVP事件总线.正在创建多个处理程序



我在继承的一个大型应用程序中工作,遇到了一些最佳实践问题。

每次用户导航到我们的"客户编辑"页面时,都会创建一个新的演示者,并设置一个视图。有一个用于客户编辑的主演示者和一个主视图。主视图中还有由主演示者的子演示者使用的子视图。在子呈现器中,我在事件总线上注册事件处理程序。

我遇到的问题是,当第二次导航到联系人编辑器时,会再次创建演示者,并再次注册这些事件。现在,当一个事件发生时,它会被处理两次,每个演示者实例一次。

演示者不被变量占用,但子视图被主视图引用。可能是视图中的这个引用阻止了事件处理程序被删除吗?我的印象是,如果该对象被垃圾收集,事件处理程序将被删除。如果不是这样,我应该从事件总线取消注册这些事件处理程序吗?

更新:演讲者没有被垃圾收集。如果我可以修改代码,在不再需要这些演示者时删除对它们的所有引用,它们会被收集吗,因此事件处理程序会被删除吗?

ResettableEventBus是专门为此而设计的-您不用为Presenter提供全局事件总线,而是将该事件总线封装在可重置版本中。然后,当该演示程序关闭时,无论是谁给它提供了事件总线,都会重置它,从而清理它可能添加的所有处理程序。

这就是GWT的Activity/Place框架中的Activities的管理方式,以防止它们泄漏。

另一个选项-给每个Presenter一个类似"stop()"或"release()"的方法,表示它是最棒的,它应该在自己之后清理-取消正在进行的RPC调用,删除对话框,取消事件处理程序。如上所述,ActivityApi有一个方法来指示它即将停止,并且它已经停止并且应该清理。

同时提供这两种方法可以很容易地避免全局事件总线出错,并且仍然可以为更细粒度的问题(长时间运行的RPC调用)提供钩子,但这两种解决方案都可以解决问题。

事件处理程序是针对EventBus内的某种集合设置和存储的独立对象实例。您的演示者只是创建它们并将它们传递给EventBus,因此在演示者的生命周期之后,处理程序仍然被引用(这就是它们继续运行的原因)。演示者可能没有被垃圾收集,因为处理程序可能仍然引用它们或它们的字段。

创建一个新的演示者后,每次检测到都会再次添加处理程序,因此解决方案是在实例化新演示者之前清除现有的处理程序,或者跟踪它们,在已经添加新的处理程序时不添加它们。

我采用的方法是重用屏幕级别的View/Presenter实例,并在重新输入时重置它们的状态。这也有助于提高性能。演示者还跟踪他们添加到EventBus的所有处理程序的HandlerRegistration实例。

我不知道Colin提到的ResettableEventBus,但这听起来也是一个很好的解决方案。

最新更新