gpt4 book ai didi

xamarin.android - ViewModels、消息和生命周期

转载 作者:行者123 更新时间:2023-12-04 16:04:47 25 4
gpt4 key购买 nike

我修改了@slodge 的一个示例,以解决我在 ViewModels 生命周期中遇到的问题。

我对 N26 做了一些修改: https://github.com/csteeg/NPlus1DaysOfMvvmCross/tree/viewmodeldisposesample/N-26-Fraggle

这个分支使用 mvxmessenger 插件来向您展示哪里出了问题。代码不是很漂亮,但表明你 wat 是不正确的。您可以看到 Id = 0 的 SubViewModel 如何继续接收消息,即使它的 View 早已消失。以及(在某些时候)HomeViewModel 如何停止接收消息。

重现步骤(包括调试输出的清理版本):

启动应用

收到 HomeViewModel:Warning:HomeViewModel 0:已创建 HomeViewModel0

点击按钮“1”

HomeViewModel:Warning:HomeViewModel 0 收到:已创建 SubViewModel0
SubViewModel:警告:收到 SubViewModel 0:已创建 SubViewModel0
HomeViewModel:警告:收到 HomeViewModel 0:已创建 FirstViewModel0
SubViewModel:警告:收到 SubViewModel 0:已创建 FirstViewModel0
FirstViewModel:警告:收到 FirstViewModel 0:已创建 FirstViewModel0

点击返回

HomeViewModel:Warning:HomeViewModel 0 received: Destroyed FirstView for viewmodel 0
SubViewModel:警告:收到 SubViewModel 0:已销毁 View 模型 0 的 FirstView
FirstViewModel:警告:收到 FirstViewModel 0:已销毁 View 模型 0 的 FirstView
HomeViewModel:警告:收到 HomeViewModel 0:已销毁 View 模型 0 的 SubFrag
SubViewModel:警告:收到 SubViewModel 0:已销毁 View 模型 0 的 SubFrag
FirstViewModel:警告:收到 FirstViewModel 0:已销毁 View 模型 0 的 SubFrag
HomeViewModel:警告:收到 HomeViewModel 0:已销毁 View 模型 0 的 DubFrag
SubViewModel:警告:收到 SubViewModel 0:已销毁 View 模型 0 的 DubFrag
FirstViewModel:警告:收到 FirstViewModel 0:已销毁 View 模型 0 的 DubFrag
你可以看到 View 在这里被破坏了,我希望 View 模型也随之消失

再次点击按钮“1”

HomeViewModel:Warning:HomeViewModel 0 收到:已创建 SubViewModel1
SubViewModel:警告:收到 SubViewModel 0:已创建 SubViewModel1
FirstViewModel:警告:收到 FirstViewModel 0:已创建 SubViewModel1
SubViewModel:警告:收到 SubViewModel 1:已创建 SubViewModel1
HomeViewModel:警告:收到 HomeViewModel 0:已创建 FirstViewModel1
SubViewModel:警告:收到 SubViewModel 0:已创建 FirstViewModel1
FirstViewModel:警告:收到 FirstViewModel 0:已创建 FirstViewModel1
SubViewModel:警告:收到 SubViewModel 1:已创建 FirstViewModel1
FirstViewModel:警告:收到 FirstViewModel 1:已创建 FirstViewModel1

在这里你可以看到, subview 模型 0 仍在接收消息。我能以某种方式告诉它应该停止向未附加的 View 模型发送消息吗?或者 View 模型可以知道没有被附加

现在,当您继续重复这些步骤相当长一段时间时,比如在模拟器中重复 15 次,一些 View 模型将停止接收消息(我猜他们被垃圾收集了)。奇怪的是,其中一个 View 是 HomeViewModel! HomeView 从未被销毁,但 homeviewmdoel 停止接收消息,因此,如果您的应用需要,则无法相应地更新 View

最佳答案

我有过类似的情况,其中 MvxMessages 仍然被不再附加到 View 的 View 模型接收和操作。

我的解决方案是将以下内容添加到基本 View 模型中:

  • 订阅方法
  • 取消订阅操作列表(这是通过 Subscribe 方法添加的)
  • 一个 UnsubscribeAll 方法

在 Android 事件 OnDestoy 中,我调用 View 模型的 UnsubscribeAll。

(作为奖励,因为标记在取消订阅操作中被引用,我不需要保留它们的另一个列表)

基础 View 模型:

    #region Messenger

/// <summary>
/// Must set the Messenger object before doing any subscribing
/// </summary>
public IMvxMessenger Messenger { get; set; }

private readonly object _messengerLock = new Object();

private List<Action> _unsubscribeActions;

/// <summary>
/// Subscribe to a message, and store in a list so can be unsubscribed automatically later
/// </summary>
/// <typeparam name="TMessage"></typeparam>
/// <param name="deliveryAction"></param>
public void Subscribe<TMessage>(Action<TMessage> deliveryAction) where TMessage: MvxMessage
{
var messenger = Messenger;
if (messenger == null) { return; }

var token = messenger.Subscribe<TMessage>(deliveryAction);

Action unsubscriber = delegate()
{
messenger.Unsubscribe<TMessage>(token);
};

lock (_messengerLock)
{
if (_unsubscribeActions == null)
{
_unsubscribeActions = new List<Action>();
}
_unsubscribeActions.Add(unsubscriber);
}
}

/// <summary>
/// Unsubscribe to all messages which have been previously subscribed to
/// </summary>
public void UnsubscribeAll()
{
if (_unsubscribeActions == null) { return; }
lock (_messengerLock)
{
foreach (var a in _unsubscribeActions)
{
a();
}
_unsubscribeActions = null;
}
}

#endregion

基础事件:

    protected override void OnDestroy()
{
var vm = ViewModel as ViewModel.BaseViewModel;
if (vm != null) { vm.UnsubscribeAll(); }
base.OnDestroy();
}

关于xamarin.android - ViewModels、消息和生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19006726/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com