Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
332 views
in Technique[技术] by (71.8m points)

xamarin.ios - UIView events and garbage collection

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.
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...