2011-02-04 4 views
4

Я заметил что-то, что может повлиять на потребление памяти любой программы, и мне хотелось бы, чтобы некоторые мысли.События UIView и сбор мусора

Я создал очень простой тестовый проект с UIViewController и UINavigationViewController. Я нажимаю свой ViewController, а затем я его всплываю. GC выполняет эту работу, и мой ViewController освобождается (вызывается деструктор). Но, если я создаю UIButton, и я зарегистрировался на одно из его событий (например, TouchInsideUp), то мой ViewController не будет выпущен. Мне нужно незарегистрировать событие, чтобы выпустить мой ViewController. Чтобы быть уверенным, что это не проблема времени, у моего тестового приложения есть кнопка, которая вызывает GC.Collect().

Я не понимаю, что объект будет сохранен в живых, если он будет доступен из стека любого потока или статической переменной. Если мой ViewController имеет право на сбор мусора, тогда будет также UIButton. Событие не должно заставлять ViewController храниться в памяти, потому что UIButton недоступен GC. В моем случае ViewController используется только NavigationController, поэтому после его всплывания он всегда должен быть собран.

С помощью нового профилировщика (моно 2.10) я, может быть, найду логический ответ, но пока я озадачен. Есть идеи?

Отредактировано: Вот несколько кодов, которые помогут понять мой случай.

Мой тест ViewController довольно прост

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 и выполняет следующие функции:

  1. Он толкнул новый экземпляр TestViewController (таким образом, только NavigationController имеет ссылку экземпляр TestViewController)
  2. TestViewController выталкивается через стандартную кнопку возврата (если я не регистрируюсь в TouchUpInside, вызывается финализатор TestViewController)
  3. Когда я возвращаюсь к MainWindow, кнопка позволяет мне позвонить GC.Collect, чтобы быть уверенным.
+0

Его невозможно точно сказать, что происходит без видя ваше решение. –

+0

Я добавил код и объяснение. Мне интересно, если под капотом регистрация событий связана с закрепленной памятью или статической переменной (в конечном итоге это событие связано с неуправляемыми ресурсами, поэтому, возможно, есть нечто большее, чем просто стандартное событие .Net). –

+0

Спасибо, ваш код помог мне увидеть проблему. Был случай, когда это могло привести к тому, что граф объектов сохранится до отключения обработчика. Я исправил это в следующем моноточе. –

ответ

0

Да, есть возможность объекта графа получать заперт в этой модели, я установил ее в следующей основной версии MonoTouch (MonoTouch 4)

Смежные вопросы