Modal View析构函数在InputAccessoryView被覆盖时未被调用
我正在呈现一个UIViewController
的模态,该视图包含各种UITextFields
。我已覆盖模式视图InputAccessoryView
,以便它显示一个简单的视图,其中一个按钮将从每个UITextField
开始ResignFirstResponder
,从而解除键盘锁定。Modal View析构函数在InputAccessoryView被覆盖时未被调用
最近我一直在打击内存相关的问题,所以我所有的控制器现在都有一个析构函数。我注意到,每当键盘显示与此覆盖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;
}
这将导致析构函数被调用!
我觉得你面对MT中的错误将被固定在MT 4貌似事件处理程序可能会阻止释放控制器:
UIView events and garbage collection
不幸的是,杰夫一直没有回复后续后续海报质疑这种影响,以及如果在MT4之前使用匿名代表进行事件是一个问题。
我认为现在有效的解决方案是手动Dispose()。
感谢您指点我正确的方向! – Luke 2011-04-06 13:32:40
我会检查我的代码是否有类似的问题。仍然会很有趣,知道a)当MT4将被发布时,以及b)什么是最好的方式来防止旧MT发布中的问题。 – Krumelur 2011-04-06 13:38:50