2013-10-10 39 views
1

我有一個複雜的視圖層次結構的應用程序,其中一個視圖控制器(我們稱之爲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的內存泄漏?

回答

2

會發生什麼情況是,存在跨越本地管理邊界的循環依賴項(與事件處理程序一起),並且當前Xamarin.iOS運行時/ GC無法檢測到此情況。

您已經找到了解決此問題的方法:通過刪除事件處理程序來打破循環依賴關係。

下面是詳細解釋的情況視頻:http://xamarin.com/evolve/2013#session-0w86u7bco2

+0

「而目前Xamarin.iOS運行/ GC無法探測到這種」 - 這聽起來像Xamarin是工作(或計劃工作)解決這種事情。 –

+2

@JohnDoe:我可以告訴你截至2014年8月30日還沒有解決方案。我認爲這是一個非常嚴重的問題,因爲它打破了任何不平凡的應用程序,但Xamarin認爲開發人員基本上做垃圾收集是合理的。 –