我在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代码订阅;到目前为止很好,没有错误。
拉纳
答案 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