2011-04-06 75 views
1

我正在呈現一個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; 
} 

這將導致析構函數被調用!

回答

1

我覺得你面對MT中的錯誤將被固定在MT 4貌似事件處理程序可能會阻止釋放控制器:

UIView events and garbage collection

不幸的是,傑夫一直沒有回覆後續後續海報質疑這種影響,以及如果在MT4之前使用匿名代表進行事件是一個問題。

我認爲現在有效的解決方案是手動Dispose()。

+0

感謝您指點我正確的方向! – Luke 2011-04-06 13:32:40

+0

我會檢查我的代碼是否有類似的問題。仍然會很有趣,知道a)當MT4將被髮布時,以及b)什麼是最好的方式來防止舊MT發佈中的問題。 – Krumelur 2011-04-06 13:38:50