memory-leaks - MonoTouch 对象引用防止垃圾回收

标签 memory-leaks xamarin.ios garbage-collection

我遇到了一个导致 MonoTouch 内存泄漏的奇怪问题。这是我的设置。

CaseTabController - UITabBarController
-- CaseMediaItemsController - UIViewController
-- CaseInfoController (irrelevant) - UIViewController

子 Controller 显示为选项卡。从子 Controller ,我试图将一些 NavigationItem(s) 添加到父 UITabBarController。但是,当我访问 ParentViewController 时,会维护一个引用,使我的对象保持事件状态并且永远不会被垃圾回收。

仅仅将以下代码添加到子 UIViewController 的 ViewDidLoad 会导致内存泄漏。

var ni = ParentViewController.NavigationItem;
ni = null;

可能父 UITabBarController 永远不会被处置,因为我的子选项卡引用它。这是 HeapShot 的输出。

从子选项卡访问 ParentViewController

HeapShot with memory leak

无法从子标签访问 ParentViewController

HeapShot without memory leak

请注意,每个内存快照都是在执行相同的不同步骤之后拍摄的。请注意没有引用 ParentViewController 的快照是如何减少实例的,因为它们正在被处理。它们被处理得如此之快,以至于我实际上是在查看有问题的 Controller 时拍摄了快照。没有访问 ParentViewController 的快照是在访问另一个 Controller 时拍摄的。在每种情况下,UITabBarController 都已从 UINavigationController 中弹出。

知道为什么 CaseMediaItemsController 在访问 ParentViewController 时保持对 CaseTabController 的引用吗?

最佳答案

要获得完整答案,请查看 http://xamarin.com/evolve/2013#session-0w86u7bco2

基本上,通过在子项中引用父项,您有一个循环,并将 NavigationItem 设置为 null还不够,还得Dispose()它也是。但是你必须确保在这个时间点你可以 Dispose() 对象。

var ni = ParentViewController.NavigationItem;
ni.Dispose ();
ni = null;

您也可以不保留对 NavigationItem 的强引用,如果您需要 ni为方便起见,将其设为 WeakReference<UINavigationItem> .这将允许它被垃圾收集。

WeakReference<UINavigationItem> ni;

public override void ViewDidLoad ()
{
    ni = new WeakReference<UINavigationItem> (ParentViewController.NavigationItem);

    //Nothing else here.
}

然后您可以使用 ni像这样:

if (ni.Target != null)
    Console.WriteLine (ni.Target.Title);

关于memory-leaks - MonoTouch 对象引用防止垃圾回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17407970/

相关文章:

haskell - 简单解析器内存不足

ios - 错误 MT2002 : Failed to resolve assembly: 'System.Drawing'

image - Monotouch 相机图像捕捉和上传

c# - Expression<TDelegate>.Compile 和垃圾收集

java - 这个匿名类对象什么时候被创建和访问,什么时候被垃圾回收?

ios - 通过命令行导出仪器跟踪数据以防泄漏

jakarta-ee - CDI |应用程序/从属范围 |内存泄漏 - javax.enterprise.inject.Instance<T> 未收集垃圾

框架回调传递接口(interface)时出现 Xamarin 异常

Java 线程垃圾是否收集

ios - 如何检查我的应用程序是否泄漏?