本文介绍了UIView事件和垃圾收集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我观察到可能影响任何程序内存消耗的东西,我想要一些想法。

我用UIViewController和UINavigationViewController创建了一个非常简单的测试项目。我推我的ViewController,然后我弹出它。 GC工作,我的ViewController被释放(析构函数被调用)。但是,如果我创建了一个UIButton并且注册了它的一个事件(例如:TouchInsideUp),那么我的ViewController就不会被释放。我需要注销事件才能释放我的ViewController。为了确保它不是时间问题,我的测试应用程序有一个调用GC.Collect()的按钮。



我不明白的是一个对象会如果可以从任何线程的堆栈或静态变量访问,则保持活动状态。如果我的ViewController符合垃圾回收的条件,那么UIButton也是。该事件不应该导致ViewController保存在内存中,因为GC无法访问UIButton。在我的情况下,ViewController仅由NavigationController使用,所以一旦弹出,它应该始终收集。



在新的探查器(单声道2.10)的帮助下,我可能会找到一个逻辑答案,但现在,我很困惑。任何想法?



已编辑:以下是一些帮助理解我的案例的代码。 我的测试的ViewController是相当简单的

 公共类TestViewController:UIViewController的{
〜TestViewController(){Console.WriteLine(终结称为); }

public UIButton Button {get; set;}
public override ViewDidLoad(){
ase.ViewDidLoad();

//如果我删除事件注册,我的TestViewController被收集。
Button = new UIButton();
Button.TouchUpInside + = ButtonTouchEventHandler;
View.AddSubview(Button);


void ButtonTouchEventHandler(object sender,EventArgs e){}
}

My MainWindow有一个NavigationController,它执行以下操作:


  1. 它推送了一个TestViewController的新实例只有NavigationController具有参考TestViewController实例)

  2. TestViewController通过标准的后退按钮弹出(如果我不注册TouchUpInside,TestViewController的终结器被调用)

  3. 当我返回到MainWindow时,一个按钮允许我调用GC.Collect只是为了确保。


解决方案

是的,在这种模式下,对象图有可能被锁定,我已经在下一个主要版本的MonoTouch(MonoTouch 4)中修复了它。


I have observed something that can affect any program's memory consumption and I would like some thoughts.

I have created a very simple test project with a UIViewController and a UINavigationViewController. I push my ViewController and then I pop it. The GC does it job and my ViewController is released (the destructor is called). But, if I create a UIButton and I registered to one of its event (ex: TouchInsideUp), then my ViewController is not released. I need to unregistered to the event in order to release my ViewController. To be sure it was not a timing problem, my test application has a button which calls GC.Collect().

What I don't understand is that an object will be kept alive if it is accessible from the stack of any thread or by a static variable. If my ViewController is eligible for garbage collection, then the UIButton will also be. The event should not cause the ViewController to be kept in memory, because UIButton is not reachable by the GC. In my case, the ViewController is only used by the NavigationController, so once it is popped it should always be collected.

With the help of the new profiler (mono 2.10) I will maybe find a logic answer, but for now, I'm perplex. Any idea?

Edited: Here's some code to help understand my case.

My test ViewController is pretty simple

public class TestViewController : UIViewController{
  ~TestViewController(){ Console.WriteLine("Finalizer called"); }

  public UIButton Button {get; set;}
  public override ViewDidLoad(){
    base.ViewDidLoad();

    // If I remove the event registering, my TestViewController is collected.
    Button = new UIButton();
    Button.TouchUpInside += ButtonTouchEventHandler;
    View.AddSubview(Button);
  }

  void ButtonTouchEventHandler(object sender, EventArgs e){}
}

My MainWindow has a NavigationController and it does the following:

  1. It pushed a new instance of TestViewController (thus only the NavigationController has a reference to the TestViewController instance)
  2. TestViewController is popped via the standard back button (if I don't register to TouchUpInside, TestViewController's finalizer gets called)
  3. When I return to the MainWindow, a button allows me to call GC.Collect just to be sure.
解决方案

Yes, there is a possibility of the object graph getting locked in this pattern, I've fixed it in the next major release of MonoTouch (MonoTouch 4)

这篇关于UIView事件和垃圾收集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-18 06:20