我有一個複雜的視圖層次結構的應用程序,其中一個視圖控制器(我們稱之爲RootVC)可以導致許多其他人。當我彈出RootVC時,我想完全釋放它。我沒有將該參考文獻存儲在某個領域或其他地方,並且認爲這足夠了。但最近我檢查了Xamarin的堆射擊,並在「所有對象」部分看到RootVC的許多實例仍保留在內存中。Monotouch(Xamarin.iOS)內存泄漏
例如這樣的:
sealed class VC1 : UIViewController
{
...
private void OpenVC2()
{
var vc2 = new VC2();
NavigationController.PushViewController(vc2, true);
}
}
sealed class VC2 : UIViewController
{
private UIButton button;
public override ViewDidLoad()
{
...
button = new UIButton(frame);
button.TouchUpInside += HandleButtonTouch;
...
}
private void HandleButtonTouch(object sender, EventArgs e)
{
NavigationController.PopViewControllerAnimated(true):
}
}
這裏的鏈接堆射擊的截圖(不能發表他們的,因爲低信譽的圖像) - http://imgur.com/a/3MYBr#1
當我在VC2,我在第一個屏幕截圖上看到類似的內容。
當我彈出VC2和VC1時,堆圖像看起來像在第二個圖像。
幾個VC2出現後,看起來像第三個屏幕截圖。
而且他們從來沒有被處置或最終確定,他們保持到最後。即使通過它們無法通過根目錄訪問。這是不可接受的,因爲內存是有限的,所有這些VC2在內存中,我們可以很容易地得到內存警告或應用程序終止。
但如果我訂閱/取消訂閱按鈕事件上的查看出現/消失這樣的:當它消失
sealed class VC2 : UIViewController
{
private UIButton button;
public override ViewDidLoad()
{
...
button = new UIButton(frame);
...
}
public override void ViewWillAppear(bool animated)
{
...
button.TouchUpInside += HandleButtonTouch;
}
public override void ViewDidDisappear(bool animated)
{
...
button.TouchUpInside -= HandleButtonTouch;
}
private void HandleButtonTouch(object sender, EventArgs e)
{
NavigationController.PopViewControllerAnimated(true):
}
}
在這種情況下VC2(連同其所有的意見,等等)被妥善處置。 〜VC2()被調用,並且所有VC2在堆圖中不再可見。
所以,這是一個問題。我做錯了什麼?我是否應該訂閱/取消訂閱上述控制事件?或者這是一個Xamarin.iOS的內存泄漏?
「而目前Xamarin.iOS運行/ GC無法探測到這種」 - 這聽起來像Xamarin是工作(或計劃工作)解決這種事情。 –
@JohnDoe:我可以告訴你截至2014年8月30日還沒有解決方案。我認爲這是一個非常嚴重的問題,因爲它打破了任何不平凡的應用程序,但Xamarin認爲開發人員基本上做垃圾收集是合理的。 –