我有一些使用服务的ViewModel,这是一个带宽密集的服务。但是,只有在应用程序中查看特定视图时才需要此服务。
在MvvmCross vNext中,我使用ViewUnRegistered
/ ViewRegistered
个事件来检测ViewModel
何时显示,并且BaseViewModel
看起来像这样:
public class BaseViewModel
: MvxViewModel
, IMvxServiceConsumer
{
public BaseViewModel()
{
ViewUnRegistered += (s, e) =>
{
if (!HasViews)
{
OnViewsDetached();
}
};
ViewRegistered += (s, e) =>
{
if (HasViews)
{
OnViewsAttached();
}
};
}
public virtual void OnViewsAttached()
{
// nothing to do here
}
public virtual void OnViewsDetached()
{
// nothing to do in this base class
}
}
然后在我的其他ViewModel
中,我将继承此内容并覆盖OnViewsAttached
和OnViewsDetached
以启动和停止服务。
现在在MvvmCross v3中,这两个Event
不再存在了。据我所知,他们在iOS上也无法正常工作。 v3还有一个新的ViewModel
生命周期,其中包含SavedState
和ReloadState
。虽然我理解SavedState
仅在ViewModel
中被调用被销毁,即使它没有显示也可能不是这样。
至于检测关联的View是否正在显示,可以假设在调用ShowViewModel
时显示View并且视图中有一些Init
参数,但这里棘手的部分是检测当View不再显示时。关于如何实现这一点的任何想法?
答案 0 :(得分:5)
在所有平台上确定View / ViewModel生命周期的这个领域相当棘手,特别是一旦开发人员开始偏离“基本”演示模型并开始使用制表符,拆分视图,弹出窗口,弹出窗口等等
MvvmCross v3目前没有通用的方法来解决这个问题。
当ios6删除viewDidUnload
时,vNext的前一个代码被破坏了(但通常被错误地使用 - 因为当ViewModel开发人员认为它是viewDidUnload
时通常不会调用它!)
仍有一个问题需要讨论未来可能的共同想法...... https://github.com/slodge/MvvmCross/issues/74
话虽如此,我最近用于此类情况的一些模式是:
对于大多数视图模型我什么也不做 - 因为这些视图模型不消耗任何资源,只能在系统需要内存时进行垃圾回收。
对于使用低强度资源的ViewModel(如计时器滴答),我通常使用MvxMessenger
将ViewModel连接到这些资源。此信使默认使用弱引用,当客户订阅/取消订阅时,本身会发出subscription change messages
使用此方法,我可以允许后台资源监视视图模型是否在内存中(并由视图引用) - 因此后台资源可以自行管理。
...虽然实际上经常(例如对于计时器滴答)然后我不断运行后台资源,无论ViewModel是否正在监听。
对于那些积极需要资源监控的罕见情况 - 例如对于需要维护活动BlueTooth SPP通道的SpheroViewModel - 然后我在ViewModel上实现自定义接口 - 例如IActiveViewModel
- 然后我从每个平台上的vies中挂接到该界面
一般来说,我是从ViewDidAppear / Disappear,OnNavigatedTo / From,OnRestart / Pause这样做的 - 但是这个确切的时间是否适合你取决于具体情况。
我怀疑,向前移动,这些资源密集型视图模型将是例外而非常态,但我希望我们会看到一些样本/食谱,这些样本/食谱展示了一些处理它们的方法。
我们也可能会看到一些人正在尝试其他持续资源情况 - 例如应用程序需要执行后台网络操作或需要在单个视图模型的生命周期之外监视地理位置(甚至可能超出应用程序)。以跨平台的方式做这些事情是一个需要考虑的“有趣”模式!