Monotouch取消订阅活动

时间:2013-07-10 12:54:35

标签: c# events memory-management xamarin.ios

我一直在MonoTouch项目中使用事件而不是代理,通常使用此模式(使用Storyboard的iPhone应用程序):

我调用PerformSegue来呈现一个新的View Controller,在PrepareForSegue方法中,我设置了View Controller的属性并使用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);
            };
        }
    }
}

(顺便说一下,我将这些已取消的事件链接起来,我需要关闭View Controller的层次结构 - 这是好还是坏是另一天的问题)

我的问题是:我最近发现,如果您不取消订阅对象的事件,那么该对象不是垃圾收集的。所以我将上面的代码更改为:

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(取消订阅事件委托中的事件)工作?我不知道还有什么地方可以取消订阅。或者我应该移动所有内容以使用通知模式(如此处所示:Should I prefer NSNotificactionCenter or .NET events when using Monotouch?)?

1 个答案:

答案 0 :(得分:0)

在您的第一个示例中,该事件会导致destinationVC引用this。由于this堆栈中的destinationVC最有可能低于导航控制器中的destinationVC,因此您实际上不会遇到问题,因为this只有{{1}}不能存在

在您的示例中不需要您的第二个示例,但它将是:

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