我以模态方式呈现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;
}
导致析构函数被调用!
答案 0 :(得分:1)
我认为您正面临MT中的一个错误,该错误将在MT 4中修复。看起来事件处理程序可能会阻止释放控制器:
UIView events and garbage collection
不幸的是,Geoff没有回复后续海报问题,这个问题对此有何影响,如果使用匿名代表参加活动则是MT4之前的问题。
我认为现在有效的解决方案是手动Dispose()。