一键取消订阅活动

本文关键字:活动 取消 一键 | 更新日期: 2023-09-27 18:21:44

我一直在MonoTouch项目中使用Events而不是delegate,通常使用以下模式(iPhone应用程序使用Storyboards):

我调用PerformSegue来呈现一个新的视图控制器,在PrepareForSegue方法中,我设置视图控制器的属性,并使用lambda表达式订阅其事件,如下所示:

public override void PrepareForSegue (UIStoryboardSegue segue, NSObject sender)
{
    if (segue.Identifier.Equals("NextViewControllerSegue")) {
        using (MyNextViewController destinationVC = segue.DestinationViewController as MyNextViewController) {  
            destinationVC.SomeProperty = "some value";
            destinationVC.Cancelled += (s, e) => {
                this.DismissViewController(false, null);
            };
        }
    }
}

(顺便说一句,我将这些取消的事件链接到我需要关闭视图控制器层次结构的地方——这是好是坏是另一天的问题)

我的问题是:我最近发现,如果不取消订阅某个对象的事件,那么该对象就不是垃圾回收对象。所以我把上面的代码改成了:

public override void PrepareForSegue (UIStoryboardSegue segue, NSObject sender)
{
    if (segue.Identifier.Equals("NextViewControllerSegue")) {
        using (MyNextViewController destinationVC = segue.DestinationViewController as MyNextViewController) {  
            destinationVC.SomeProperty = "some value";
            destinationVC.Cancelled += Cancel;
        }
    }
}
protected void Cancel (object sender, EventArgs e)
{
    (sender as MyNextViewController).Cancelled -= Cancel;
    this.DismissViewController(false, null);
}

我的问题是:这种模式是处理事情的好方法吗?方法2(取消预订活动代表中的活动)是否有效?我不知道还有什么地方可以取消订阅。或者,我应该将所有内容都移动到使用通知模式(如这里所建议的:在使用Monotouch时,我应该更喜欢NSNotificationCenter还是.NET事件?)?

一键取消订阅活动

在第一个示例中,该事件将导致destinationVC引用this。由于在导航控制器中,this在堆栈中很可能比destinationVC低,所以您实际上没有问题,因为destinationVC的寿命不如this长。

你的例子中不需要第二个例子,但如果:

  • 控制器订阅将存在很长时间的对象上的事件,如Model/ViewModel类
  • 控制器订阅导航控制器堆栈中前一个控制器上的事件(模式控制器也是如此)