私はプログラムのメモリ消費に影響を与える何かを観察しましたが、私はいくつかの考えをしたいと思います。UIViewのイベントとガーベジコレクション
私はUIViewControllerとUINavigationViewControllerで非常に簡単なテストプロジェクトを作成しました。私は私のViewControllerを押して、私はそれをポップアップ。 GCはそれを実行し、私のViewControllerは解放されます(デストラクタが呼び出されます)。しかし、UIButtonを作成してそのイベント(例:TouchInsideUp)の1つに登録した場合、ViewControllerは解放されません。 ViewControllerをリリースするためにイベントの登録を解除する必要があります。タイミングの問題ではないことを確認するため、テストアプリケーションにGC.Collect()を呼び出すボタンがあります。
私が理解していないことは、オブジェクトがスレッドのスタックや静的変数からアクセスできる場合、オブジェクトが生きているということです。私のViewControllerがガベージコレクションに適格であるならば、UIButtonもそうです。 UIButtonにGCが到達できないため、イベントによってViewControllerがメモリ内に保持されてはなりません。私の場合、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){}
}
私のメインウィンドウにはNavigationControllerを持っており、それが次のことを行います。
- それはTestViewControllerの新しいインスタンスをプッシュ(これだけNavigationControllerへの参照を持っていますTestViewControllerインスタンス)
- TestViewControllerは標準の戻るボタンでポップされます(TouchUpInsideに登録しないと、TestViewControllerのファイナライザが呼び出されます)
- MainWindowに戻ると、ボタンをクリックするとGC.Collectを呼び出すことができます。
でそれを修正しましたあなたの解決策を見てください。 –
私はいくつかのコードと説明を追加しました。イベント登録に固定されたメモリや静的変数が含まれていると(最終的にイベントが管理されていないリソースを処理するため、標準の.Netイベント以上のものがあるかもしれない)と思っています。 –
ありがとうございます、あなたのコードは、私が問題を見るのを助けました。ハンドラを切断するまで、オブジェクトグラフが保持される場合がありました。私は次のモノタッチでこれを修正しました。 –