MvvmCross:在ViewModel中引发事件的最佳方式
本文关键字:事件 最佳 方式 ViewModel MvvmCross | 更新日期: 2023-09-27 18:05:39
我目前有一个视图(Android Fragment)和一个相应的ViewModel。现在我想在ViewModel中引发一个事件,View可以订阅这个事件。
最好的存档方式是什么?我听说一个常规的c#事件(委托)会导致内存泄漏?这就是使用WeakSubscribe函数的原因吗?如何将其绑定到事件?
为了防止视图中的内存泄漏,您订阅的每个事件都需要取消订阅,无论是使用WeakSubscribe
还是像往常一样订阅事件。
一个常见的场景是订阅:
- Android
OnResume()
- iOS
ViewWillAppear()
则在
上解除订阅- Android
OnPause()
- iOS
ViewWillDisappear()
WeakSubscribe
如果你想"监听"ViewModel属性的变化,WeakSubscribe
就派上用场了:
private IDisposable _selectedItemToken;
_selectedItemToken = ViewModel.WeakSubscribe(() =>
ViewModel.SelectedItem, (sender, eventArgs) => {
// do something
});
请注意,
WeakSubscribe()
返回一个MvxWeakEventSubscription,也是IDisposable
。您需要在视图中保存对该订阅的引用,并在不再需要该视图时处理它。保留该引用有两个原因:
- 你可以稍后处理
- 如果你不保留它,你的lambda事件处理程序可能不总是工作
后来…
_selectedItemToken?.Dispose();
正常事件订阅
如果您只需要订阅ViewModel中的另一种事件(而不是属性更改),则实际上不需要WeakSubscribe
。您可以向ViewModel添加一个事件监听器,就像您对任何对象所做的那样。
ViewModel.AnEvent += YourDelegate;
后来…
ViewModel.AnEvent -= YourDelegate;
不要忘记最后一步。这将防止内存泄漏。就像我说的,Android
OnPause()
和iOSViewWillDisappear()
是做这件事的好地方。
这样,当视图被处置时,您的ViewModel就不会卡在内存中,因此您的视图可以正确地进行垃圾收集。
如果您订阅了临时对象中的事件,并且在释放临时对象之前没有取消订阅,则可能会造成泄漏。在您的情况下,这种可能性很小,因为视图模型很可能只创建一次。
因为你正在使用mvvm,事件的替代方案是信使,你可以在流行的mvvm框架中找到实现,如MvvmLight或MvvmCross。这为您提供了真正解耦的事件,因为您只需要知道消息的格式,而不需要知道有关发送方的任何信息(在您的示例中是ViewModel)。使用messenger,你只能订阅一个消息类型,发送者可以在应用程序的任何地方。