遇到MvxPropertyChangedListener奇怪的行为和变通方法

时间:2014-01-10 02:57:51

标签: mvvmcross

我在MvvmCross中很新,所以我可能只是做错了事;或不。

以防万一,这也是一种解决方法,并指出寻找其他开发人员。

使用: Windows Phone 8

问题:在“视图”页面中,使用MvxPropertyChangedListener订阅可以使用一段时间,然后停止。

场景: ViewModel有一个属性IsBusy,由于特定原因,我需要从View页面代码(.xaml.cs)访问。我认为它的工作方式是......

public LoadingView()
{
    InitializeComponent();

    // until loaded, we can not access viewmodel
    Loaded += (sender, args) =>
    {
        var viewModel = (LoadingViewModel) ViewModel;

        // add listener
        new MvxPropertyChangedListener(viewModel).Listen(() => viewModel.IsBusy, () =>
        {
            // do something
        });
    };
}

现在,用户单击一个命令按钮,我在其上使用jsonRestClient调用异步任务休息方法;任务完成后,isBusy设置为false;

注意:我还将isBusy绑定到xaml文件中的元素(到progressBar可见性)。

在WP Emulator中,单击该按钮会引发侦听器事件,但只会发生两到三次。之后,侦听器中的代码不再执行。有趣的是,xaml绑定仍在更新;

我不知道GC是如何发挥作用的;因为该属性位于ViewModel本身;

解决方法:没有太多时间来调查此问题;相反,我现在正在使用 IMvxMessenger ,并从我的View代码订阅;到目前为止很好,没有错误。

拉​​纳

1 个答案:

答案 0 :(得分:2)

MvvmCross在其订阅中大量使用weak个引用 - 例如对于像ViewModel属性订阅和信使订阅之类的东西。

MvxPropertyChangedListener的来源位于https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross/ViewModels/MvxPropertyChangedListener.cs

此类订阅使用以下方式查看模型更改:

_token = _notificationObject.WeakSubscribe(NotificationObjectOnPropertyChanged);

并且_token存储在私有成员变量中。

由于您的代码将属性侦听器创建为临时对象,因此该对象将存在一段时间,但在某个时刻将由系统确定为垃圾收集。当它是GC时,_token也是如此 - 因此订阅本身将停止工作。

要解决此问题,请将属性侦听器存储在视图的字段中:

 _isBusyListener = new MvxPropertyChangedListener //....

这将阻止它进行GC