我正在呈現一個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;
}
這將導致析構函數被調用!
感謝您指點我正確的方向! – Luke 2011-04-06 13:32:40
我會檢查我的代碼是否有類似的問題。仍然會很有趣,知道a)當MT4將被髮布時,以及b)什麼是最好的方式來防止舊MT發佈中的問題。 – Krumelur 2011-04-06 13:38:50