我试图找出如何在控件的超级视图中加入ViewDidUnload
。为了说明我需要这个的原因,请考虑我的ControlFactory
类,它产生UIButton
s(以及其他控件):
internal static class ControlFactory
{
private static readonly IObservable<Unit> sharedDynamicTypeChanged = TinyIoCContainer.Current
.Resolve<ISystemNotificationsService>()
.DynamicTypeChanged
.Publish()
.RefCount();
public static UIButton CreateButton()
{
return new DynamicTypeAwareButton(sharedDynamicTypeChanged, UIFont.PreferredHeadline);
}
}
这里的想法是工厂生产的每个UIButton
都会根据用户的动态类型设置自动缩放其字体。我的DynamicTypeAwareButton
是一个内部类,如下所示:
private sealed class DynamicTypeAwareButton : UIButton
{
private readonly IObservable<Unit> dynamicTypeChanged;
private readonly UIFont font;
private IDisposable subscription;
public DynamicTypeAwareButton(IObservable<Unit> dynamicTypeChanged, UIFont font)
{
this.dynamicTypeChanged = dynamicTypeChanged;
this.font = font;
}
public override void MovedToSuperview()
{
base.MovedToSuperview();
// TODO: figure out when to subscribe/unsubscribe
this.subscription = this.dynamicTypeChanged
.StartWith(Unit.Default)
.Subscribe(_ => this.UpdateFont());
}
private void UpdateFont()
{
this.Font = this.font;
}
}
问题,如评论中所述,我需要知道按钮的超级视图何时被卸载,以便我可以处理订阅。我可以很容易地访问超级视图,但是当卸载超级视图时,我找不到任何要通知的挂钩。
有谁知道实现这一目标的任何方法?
答案 0 :(得分:1)
而不是MovedToSuperView
使用WillMoveToSuperView
- 它将被调用两次,一次将Button添加到View(即=&gt;订阅)时,以及一次当Button即将被删除时(其中newSuperview
将为null)。
此外,您可以使用SerialDisposable
:
private sealed class DynamicTypeAwareButton : UIButton
{
private readonly IObservable<Unit> dynamicTypeChanged;
private readonly UIFont font;
private SerialDisposable subscription = new SerialDisposable();
public override void WillMoveToSuperView(UIView newView)
{
base.WillMoveToSuperView();
// Whenever SerialDisposable.Disposable is assigned, it throws
// away the previous one. That means, even if the Button gets
// moved to a new non-null View, we're still not leaking a
// subscription
if (newView != null)
{
this.subscription.Disposable = this.dynamicTypeChanged
.StartWith(Unit.Default)
.Subscribe(_ => this.UpdateFont());
}
else
{
this.subscription.Disposable = Disposable.Empty;
}
}
public void UpdateFont()
{
/* ... */
}
}