我注意到由于同一ViewModel的多个实例,多次调用了MvxMessenger订阅。我读了一些关于取消订阅和处理令牌(它可以工作并阻止多次调用)的内容,但我希望看到ViewModel自然地被垃圾收集,并且看到了Messenger订阅。
我想为Android设置类似于此https://github.com/slodge/MessengerHacking的测试项目。所以这是两个ViewModels
public class FirstViewModel : MvxViewModel
{
private string _hello = "Hello MvvmCross";
public string Hello
{
get { return _hello; }
set { _hello = value; RaisePropertyChanged(() => Hello); }
}
private MvxCommand _showSecond;
public ICommand ShowSecond {
get {
_showSecond = _showSecond ?? new MvxCommand(() => ShowViewModel<SecondViewModel> ());
return _showSecond;
}
}
}
和
public class SecondViewModel : MvxViewModel
{
private readonly IMvxMessenger _messenger;
private readonly MvxSubscriptionToken _token;
public SecondViewModel(IMvxMessenger messenger) {
_messenger = messenger;
_token = _messenger.Subscribe<MyMessage> ((message) => {
Debug.WriteLine("incoming message");
});
}
private MvxCommand _send;
public ICommand Send {
get {
_send = _send ?? new MvxCommand(() => _messenger.Publish (new MyMessage (this)));
return _send;
}
}
private MvxCommand _garbageCollect;
public ICommand GarbageCollect {
get {
_garbageCollect = _garbageCollect ?? new MvxCommand(() => GC.Collect ());
return _garbageCollect;
}
}
}
然后我只有两个MvxActivities绑定到这些ViewModels。如果我转到SecondViewModel并单击发送,我会看到订阅的事件触发一次。如果我在First和SecondViewModel之间来回切换,则会生成这些事件订阅,然后单击Send会触发每个订阅。单击GarbageCollect似乎没有任何区别(我希望看到它在单击此项后仅调用一次)。
感觉好像当我从SecondViewModel点击后退按钮时,一旦MvxActivity被销毁,那么SecondViewModel应该有资格进行垃圾收集。
我注意到的另一件事是,即使我订阅而不将其保存到令牌中,行为也是一样的。我成功获取事件以停止触发的唯一方法是保存令牌并在令牌上调用Unsubscribe或Dispose,但感觉在这种情况下SecondViewModel仍然没有收集垃圾。
这可能与最近对Xamarin.Android的更改有关吗?或者有些东西我还没有得到!
非常感谢
答案 0 :(得分:1)
我知道答案为时已晚,但为了参考:
简答:
在视图(MvxActivity)中,处理DestroyCalled事件,如下所示:
DestroyCalled += (s, e) =>
{
if (ViewModel is IDisposable)
(ViewModel as IDisposable).Dispose();
};
在viewmodel中,实现IDisposable接口:
public new void Dispose()
{
base.Dispose();
//Unsubscribe messages here
}
长答案:
http://slodge.blogspot.co.uk/2013/11/n42-is-my-viewmodel-visible-can-i-kill.html