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

问题描述

我观察到一些会影响任何程序的内存消耗的东西,我想提出一些想法.

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

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

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().

我不明白的是,如果可以从任何线程的堆栈或静态变量访问对象,则该对象将保持活动状态.如果我的 ViewController 有资格进行垃圾回收,那么 UIButton 也将是.该事件不应导致 ViewController 保留在内存中,因为 GC 无法访问 UIButton.在我的例子中,ViewController 只被 NavigationController 使用,所以一旦它被弹出,它应该总是被收集.

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.

在新的分析器(mono 2.10)的帮助下,我可能会找到一个合乎逻辑的答案,但现在,我很困惑.任何的想法?

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.

我的测试 ViewController 非常简单

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){}
}

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

My MainWindow has a NavigationController and it does the following:

  1. 它推送了一个新的 TestViewController 实例(因此只有 NavigationController 引用了 TestViewController 实例)
  2. TestViewController 通过标准的后退按钮弹出(如果我没有注册到 TouchUpInside,TestViewController 的终结器会被调用)
  3. 当我返回 MainWindow 时,一个按钮允许我调用 GC.Collect 只是为了确定.

推荐答案

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

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