1

我一直在 MonoTouch 项目中使用事件而不是委托,通常使用这种模式(使用故事板的 iPhone 应用程序):

我调用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);
            };
        }
    }
}

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

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

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 时我应该更喜欢 NSNotificactionCenter 还是 .NET 事件?)?

4

1 回答 1

0

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

您的示例中不需要您的第二个示例,但如果:

  • 控制器订阅将存在很长时间的对象上的事件,例如 Model/ViewModel 类
  • 控制器订阅导航控制器堆栈中前一个控制器上的事件(模态控制器也是如此)
于 2013-07-12T12:31:37.010 回答