我有一个奇怪的问题,导致了MonoTouch中的内存泄漏。这是我的装置。
CaseTabController - UITabBarController
-- CaseMediaItemsController - UIViewController
-- CaseInfoController (irrelevant) - UIViewController子控制器显示为选项卡。从子控制器中,我尝试向父NavigationItem添加一些UITabBarController。但是,当我访问ParentViewController时,会维护一个引用,使我的对象保持活动状态,并且永远不会被垃圾收集。
仅仅将以下代码添加到子UIViewController的ViewDidLoad中就会导致内存泄漏。
var ni = ParentViewController.NavigationItem;
ni = null;愿父母UITabBarController永远不会被处置,因为我的子选项卡引用它。这是HeapShot的输出。
具有从子选项卡访问ParentViewController 的

没有从子选项卡访问ParentViewController 的

注意,除了步骤之外,每个内存快照都是在执行相同的操作后拍摄的。请注意,不引用ParentViewController的快照是如何减少实例的,因为它们正在被释放。它们被处理得如此之快,以至于我实际上是在查看相关控制器时拍下了快照。没有访问ParentViewController的快照是在访问另一个控制器时拍摄的。在每种情况下,UITabBarController都是从UINavigationController中弹出的。
知道为什么CaseMediaItemsController在访问ParentViewController时保持对CaseTabController的引用吗?
发布于 2013-07-02 08:39:25
要获得完整的答案,请看http://xamarin.com/evolve/2013#session-0w86u7bco2
基本上,通过引用子元素中的父元素,您有一个循环,而将NavigationItem设置为null是不够的,您还必须将其设置为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);https://stackoverflow.com/questions/17407970
复制相似问题