【发布时间】:2015-04-06 21:54:49
【问题描述】:
当我在 ReactiveUI 中将“后退按钮”绑定到路由器时,我的 ViewModel 不再被垃圾收集(我的视图也是)。这是一个错误,还是我在做一些愚蠢的事情?
这是我的 MeetingPageViewModel:
public class MeetingPageViewModel : ReactiveObject, IRoutableViewModel
{
public MeetingPageViewModel(IScreen hs, IMeetingRef mRef)
{
HostScreen = hs;
}
public IScreen HostScreen { get; private set; }
public string UrlPathSegment
{
get { return "/meeting"; }
}
}
这是我的 MeetingPage.xaml.cs 文件:
public sealed partial class MeetingPage : Page, IViewFor<MeetingPageViewModel>
{
public MeetingPage()
{
this.InitializeComponent();
// ** Comment this out and both the View and VM will get garbage collected.
this.BindCommand(ViewModel, x => x.HostScreen.Router.NavigateBack, y => y.backButton);
// Test that goes back right away to make sure the Execute
// wasn't what was causing the problem.
this.Loaded += (s, a) => ViewModel.HostScreen.Router.NavigateBack.Execute(null);
}
public MeetingPageViewModel ViewModel
{
get { return (MeetingPageViewModel)GetValue(ViewModelProperty); }
set { SetValue(ViewModelProperty, value); }
}
public static readonly DependencyProperty ViewModelProperty =
DependencyProperty.Register("ViewModel", typeof(MeetingPageViewModel), typeof(MeetingPage), new PropertyMetadata(null));
object IViewFor.ViewModel
{
get { return ViewModel; }
set { ViewModel = (MeetingPageViewModel)value; }
}
}
然后我运行,看看发生了什么,我使用 VS 2013 Pro,并打开内存分析器。我还(作为测试)对所有代进行强制 GC 收集并等待终结器。当上面取消注释该行时,当一切都完成后,就有了 MeetingPage 和 MeetingPageViewModel 的三个实例。如果我删除 BindCommand 行,则没有实例。
我的印象是这些会自行消失。问题是 HostScreen 对象还是引用了比此 VM 寿命更长的对象的路由器?这样就可以解决问题了吗?
如果是这样,连接后退按钮的建议是什么?使用 Splat 和 DI?非常感谢!
【问题讨论】:
标签: garbage-collection windows-store-apps reactiveui