我注意到由于同一 ViewModel 的多个实例,MvxMessenger 订阅被多次调用。我阅读了一些关于取消订阅和处理 token 的内容(这有效并防止多次调用),但我希望看到 ViewModel 被自然地垃圾收集,Messenger 订阅也随之被收集。
我想为 Android 设置一个与此类似的测试项目 https://github.com/slodge/MessengerHacking .所以这是两个 ViewModel
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 绑定(bind)到这些 ViewModel。如果我转到 SecondViewModel 并单击发送,我会看到订阅的事件触发一次。如果我在 First 和 SecondViewModel 之间来回切换,这些事件订阅会建立起来,单击“发送”会触发它们中的每一个。单击 GarbageCollect 似乎没有任何区别(我希望看到它在单击后仅被调用一次)。
感觉好像当我从 SecondViewModel 单击后退按钮时,一旦 MvxActivity 被销毁,SecondViewModel 就应该有资格进行垃圾回收。
我注意到的另一件事是,即使我订阅而不将其保存到 token 中,行为也是相同的。我成功让事件停止触发的唯一方法是保存 token 并对 token 调用 Unsubscribe 或 Dispose,但在这种情况下感觉 SecondViewModel 仍然没有收集垃圾。
这可能与最近对 Xamarin.Android 的更改有关吗?还是有什么我不明白的!
非常感谢
最佳答案
我知道现在回答为时已晚,但为了引用:
简答:
在 View (MvxActivity)中,像这样处理 DestroyCalled 事件:
DestroyCalled += (s, e) =>
{
if (ViewModel is IDisposable)
(ViewModel as IDisposable).Dispose();
};
在 View 模型中,实现 IDisposable 接口(interface):
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
关于android - MvvmCross Android - ViewModel 从未被垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30798429/