如前所述,某些MvvmCross视频(http://www.youtube.com/watch?v=cYu_9rcAJU4&feature=youtu.be&t=33m41s)
我正在尝试从我的viewmodel中移除强引用到我的视图。
实现了WeakSubscribe(),其中使用了PropertyChanged + =我现在遇到了一些使用Action来允许视图观察的场景。我认为这将导致潜在的内存泄漏,所以试图根除。
但是 - WeakReference的工作原理是连接到一个INotifyPropertyChanged源:
那么我是否应该重构我的代码以抛弃Action并通过PropertyChanged触发以通过弱引用通知视图?
以下是一些仅供参考的示例代码 - 当前强引用的架构。
视图模型
public event Action Loaded;
public HomeViewModel()
{
FeaturedProductCategoryViewModel = new FeaturedProductsViewModel();
FeaturedProductCategoryViewModel.OnPopulated += () =>
{
if (Loaded != null) Loaded();
};
}
查看
public MainHomePageView()
: base(GetNibName("MainHomePageView"), null)
{
this.EnableLandscapeRotation ();
}
protected override void ViewJustLoaded()
{
this.ViewModel.Loaded += LoadControls;
}
void LoadControls()
{
//load controls when view model is populated
}
答案 0 :(得分:1)
MvvmCross弱引用方法背后的驱动思路是ViewModels永远不应该引用Views - 就好像它们那样,它可以导致Views包含对其包含Views的引用。
这方面的一些背景是https://stackoverflow.com/a/14734264/373321
如果Loaded
这样的事件有点非正统Action
类型,我认为可以使用新的WeakSubscribe
扩展方法和处理程序订阅。
或者,您可以将Loaded
更改为EventHandler
类型,然后使用WeakSubscribe(this EventInfo eventInfo, ...
扩展方法:
// ViewModel - define event
public event EventHandler Loaded;
// View - subscription
IDisposable _subscription;
// View - in ViewDidLoad
_subscription = typeof(HomeViewModel)
.GetEvent("Loaded")
.WeakSubscribe(this.ViewModel, OnLoaded);
// View - event handler
public void OnLoaded(object sender, EventArgs e)
{
LoadControls();
}
答案 1 :(得分:0)
我认为更好的解决方案是在视图模型中使用bool属性(称为IsBusy),然后在开始加载时将IsBusy设置为true。完成加载后 - 将其设置为false;然后在您的视图中,使用mvvmcross属性侦听器来执行加载完成
listener = new MvxPropertyChangedListener(IncidentViewModel).Listen<bool>(
() => IncidentViewModel.IsBusy,
() =>
{
if (IncidentViewModel != null && !IncidentViewModel.IsBusy)
{
LoadControls();
}
});