首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >防止垃圾收集的MonoTouch对象引用

防止垃圾收集的MonoTouch对象引用
EN

Stack Overflow用户
提问于 2013-07-01 15:17:45
回答 1查看 489关注 0票数 3

我有一个奇怪的问题,导致了MonoTouch中的内存泄漏。这是我的装置。

代码语言:javascript
复制
CaseTabController - UITabBarController
-- CaseMediaItemsController - UIViewController
-- CaseInfoController (irrelevant) - UIViewController

子控制器显示为选项卡。从子控制器中,我尝试向父NavigationItem添加一些UITabBarController。但是,当我访问ParentViewController时,会维护一个引用,使我的对象保持活动状态,并且永远不会被垃圾收集。

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

代码语言:javascript
复制
var ni = ParentViewController.NavigationItem;
ni = null;

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

具有从子选项卡访问ParentViewController

没有从子选项卡访问ParentViewController

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

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-02 08:39:25

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

基本上,通过引用子元素中的父元素,您有一个循环,而将NavigationItem设置为null是不够的,您还必须将其设置为Dispose()。但是,您必须确保此时可以释放()对象。

代码语言:javascript
复制
var ni = ParentViewController.NavigationItem;
ni.Dispose ();
ni = null;

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

代码语言:javascript
复制
WeakReference<UINavigationItem> ni;

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

    //Nothing else here.
}

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

代码语言:javascript
复制
if (ni.Target != null)
    Console.WriteLine (ni.Target.Title);
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17407970

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档