通过在父级上呈现新的视图控制器 viewWillDisappear 在我取消订阅事件时触发

Posted

技术标签:

【中文标题】通过在父级上呈现新的视图控制器 viewWillDisappear 在我取消订阅事件时触发【英文标题】:Through presenting new view controller viewWillDisappear on parent is triggered where I unsubscribe from the events 【发布时间】:2015-08-20 11:53:54 【问题描述】:

在我的主视图控制器上,我有一个显示另一个视图控制器的按钮,其中一些设置可以更改:

PresentViewController (new UINavigationController(anotherViewController), true, null);

anotherViewController 的解雇应该由父母负责。我还必须知道是否发生了某些变化(已保存)。因此我使用事件。

我在父视图控制器的viewWillAppear 中附加了事件处理程序

anotherViewController.DismissMe += CancelEventHandler;
anotherViewController.SaveFilter += SaveEventHandler;

viewWillDisappear 我正在退订它

anotherViewController.DismissMe -= CancelEventHandler;
anotherViewController.SaveFilter -= SaveEventHandler;

因为viewWillDisappear 是在新的视图控制器出现时触发的,所以我会自动取消订阅这些事件。当我想触发 anotherViewController 中的事件时,我不能,因为没有人订阅我的事件。

我必须取消订阅这些事件,否则视图控制器永远不会被释放。

我该如何解决这种情况?

【问题讨论】:

viewWillAppearviewWillDisappear 不是放置这种逻辑的好委托方法,因为它们可能随时运行且永远不会运行。我会在init 订阅并在dealloc 取消订阅,因为它们只被调用一次。 @Simon:因此我使用了一个布尔变量来知道我是否订阅过一次。 init 或构造函数是个好主意吗?有一些side effects,在某些情况下会给视图控制器的生命周期带来一种混乱。我必须将代码从viewDidLoad 移动到initdealloc 是不是太晚了?或者这里的内存管理可以吗? 我真的不知道 xamarin 或 monotouch 是如何工作的,但我知道 ios 视图控制器的生命周期。只要您不触摸init 中的viewController's 视图,我会说您在那里订阅。对于dealloc,这是取消订阅和清理钩子的地方。因此,如果您不需要view 属性,请将您的订阅添加到init,否则将其添加到loadView超级调用之后。 如果我遵循您的方法,那么我可以保留我的代码(在viewDidLoad 中订阅)并在dealloc 中取消订阅。这是个好主意吗?我想到的另一种方法是在这里使用另一个布尔变量。然后我必须在每个礼物上设置它并解雇。在viewWillDisappear 中,我可以检查是否应该取消订阅。 看看这个副本? ***.com/questions/1816614/… 【参考方案1】:

我当前的解决方案如下所示:

在展示新的视图控制器之前,我订阅了取消和保存的事件(自定义创建的事件)。因为当呈现的视图控制器关闭或保存操作完成时呈现的视图控制器会获取此事件(取消、保存),所以当我检索其中一个事件时,我会删除对此事件的订阅(取消、保存)。事件处理程序本身中的 Id est 我正在取消订阅该事件。

这样可以确保我只订阅一次,并且在需要时我也会取消订阅。

对此有更多的方法,可以在我的问题的 cmets 中找到。

【讨论】:

以上是关于通过在父级上呈现新的视图控制器 viewWillDisappear 在我取消订阅事件时触发的主要内容,如果未能解决你的问题,请参考以下文章

如果在子级上验证失败,则不会在父级上调用IValidatableObject.Validate

即使没有悬停在父级上,子元素也会出现

如何将 MouseListener 留在 ChildComponent 上但正确跟踪鼠标在父级上的进入和退出?

来自父级的 TextField 默认值未在子级上呈现

将列表框项内的命令绑定到视图模型父级上的属性

在视图呈现之前从父级设置子组件属性