重写InputAccessoryView时未调用模态视图析构函数

时间:2011-04-06 11:57:55

标签: iphone ios xamarin.ios

我以模态方式呈现UIViewController,该视图包含各种UITextFields。我已经覆盖了模态视图InputAccessoryView,因此它显示了一个简单的视图,其中一个按钮将ResignFirstResponder来自UITextField,从而解除了键盘。

最近我一直在打击与内存相关的问题,所以我的所有控制器现在都有一个析构函数。我注意到,每当模态视图被解除时,只要键盘显示为覆盖InputAccessoryView,就不会调用析构函数。这是否意味着UIViewController没有被销毁?我是否错误地显示了InputAccessoryView?

InputAccessoryView代码如下:

bool accessoryViewInit = false;
UIView accessoryView = new UIView(new RectangleF(0,0,320,30));

public override UIView InputAccessoryView 
{
    get 
    {
        if (!accessoryViewInit)
        {
            accessoryView.BackgroundColor = UIColor.FromRGBA(0.0f, 0.0f, 0.f, 0.5f);
            UIButton dismiss = new UIButton(new RectangleF(50,1, 200, 28));
            dismiss.BackgroundColor = UIColor.Blue;
            dismiss.SetTitle("Close Keyboard", UIControlState.Normal);
            dismiss.TouchUpInside += delegate(object sender, EventArgs e) {
                field1.ResignFirstResponder();
                field2.ResignFirstResponder();
                field3.ResignFirstResponder();
            };
            accessoryView.AddSubview(dismiss);
        }       
        return accessoryView;
    }
}

我有一种感觉,这是因为我正在为按钮的TouchUpInside事件分配一个委托,它是否保留对此的引用,从而阻止整个控制器被销毁?

我创建了一个示例项目,可以在https://github.com/lukewhitt/InputAccessoryView-test

找到

要重新创建问题:通过触摸大红色按钮运行应用程序,显示模态视图。现在,如果在不显示键盘的情况下关闭视图,则将调用析构函数。如果您使用UITextField的第一响应者(显示键盘和InputAccessoryView)然后关闭模态控制器,则不会调用析构函数。

修改

看起来这是Monotouch中的一个错误,将在即将发布的版本中修复。为了解决问题,似乎在分配事件时不能使用匿名委托。所以dismiss.TouchUpInside将成为:

public override UIView InputAccessoryView {
// code before
    dismiss.TouchUpInside += HandleDismissTouch;
// rest of code
}

private void HandleDismissTouch (object sender, EventArgs e)
{
    field1.ResignFirstResponder();
    field2.ResignFirstResponder();
    field3.ResignFirstResponder();
}

然后在解散模态控制器的代码中,我添加了以下内容:

if (dismiss != null)
{
    dismiss.TouchUpInside -= HandleDismissTouch;
    dismiss.Dispose();
    dismiss = null;
}

导致析构函数被调用!

1 个答案:

答案 0 :(得分:1)

我认为您正面临MT中的一个错误,该错误将在MT 4中修复。看起来事件处理程序可能会阻止释放控制器:

UIView events and garbage collection

不幸的是,Geoff没有回复后续海报问题,这个问题对此有何影响,如果使用匿名代表参加活动则是MT4之前的问题。

我认为现在有效的解决方案是手动Dispose()。