2011-07-27 4 views
3

私のカスタムボタン、MyButton(これはUIButtonから継承)への参照を保持しているものがあり、スーパービューから削除しない限り、ガベージコレクションされないようです。これにより、オンになっているView Controllerもファイナライズされずに収集されます。button.RemoveFromSuperview()を呼び出さない限りMonoTouchがカスタムUIButtonをガベージコレクションしないのはなぜですか?

私のカスタムボタンがありますが、ビューアーコントローラーに標準UIButtonがあります。これは、収集するためにスーパービューから削除する必要はありません。違いは何ですか?私とかなり似ています。

このコードを参照してください。無関係な行は、例えば、削除されました。サンプルについての注意点:

- MyButtonはかなり空です。ちょうどコンストラクタと他の何も上書きされません。 UINavigationController

上にある

-Imagine MyViewControllerからLoadView()だけ、ボタンを作成し、それぞれのイベントをフックし、ビューに追加

_buttonを-Touching NAVコントローラ

に別の MyViewControllerを押すことになります

- Navコントローラからビューコントローラをポップアップするときに参照クリーンアップを行っていますViewDidAppear()

-CleanUpRefs()すべてのオブジェクトをガベージコレクションするためには、スーパービューから_myButtonを削除する必要があることがわかります。一方、_buttonは、削除する必要はありません。

- すべてのサブビューを含む、MyViewController全体が収集されることを期待していますが、ナビコントローラーからポップアップしたときに、_myButton.RemoveFromSuperview()がこれを起こさないようにコメントします。

public class MyViewController : UIViewController 
{ 
    private UIButton _button; 
    private MyButton _myButton; 
    private MyViewController _nextController; 

    public override void LoadView() 
    { 
     base.LoadView(); 

     _button = UIButton.FromType(UIButtonType.RoundedRect); 
     _button.TouchUpInside += PushNewController; 
     View.AddSubview(_button); 

     _myButton = new MyButton(); 
     _myButton.TouchUpInside += MyButtonTouched; 
     View.AddSubview(_myButton); 
    } 

    private void PushNewController(object sender, EventArgs e) 
    { 
     _nextController = new MyViewController(); 
     NavigationController.PushViewController(_nextController, true); 
    } 

    private void MyButtonTouched(object sender, EventArgs e) 
    { 
     Console.WriteLine("MyButton touched"); 
    } 

    public void CleanUpRefs() 
    { 
     //_button.RemoveFromSuperview(); 
     _myButton.RemoveFromSuperview(); 
     // remove reference from hooking up event handler 
     _button.TouchUpInside -= PushNewController; 
     _myButton.TouchUpInside -= MyButtonTouched; 
     _button = null; 
     _myButton = null; 
    } 

    public override void ViewDidAppear(bool animated) 
    { 
     base.ViewDidAppear(animated); 

     if(_nextController != null) 
     { 
     _nextController.CleanUpRefs(); 
     _nextController = null; 
     } 
    } 
} 

にMyButtonは、それが継承されることにまっすぐにUIButtonではないという事実と違うものがありますかのように思えます。しかし、再度、特に、それを削除する必要がないようなUIButtonがある場合は、RemoveFromSuperview()を呼び出すことによって削除されている余分な参照カウントがあるのでしょうか?

(私は本当に悪いレイアウトのために謝罪、stackoverflowのは、右のコードスニペットの上に箇条書きのレイアウトの問題を持っているようだ)

アップデート:私はMonoTouchでチームにバグレポートを提出しました。サンプルプロジェクトを実行したい場合はそこからサンプルプロジェクトをダウンロードできます。 Bug 92

答えて

3

このシナリオでガベージコレクションが行われない理由は、MonoTouchのバグです。

次回リリースのMonoTouchには、これに対する修正が含まれています。お急ぎの場合、あなたは私がここに置かコピーしてあなたの/Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dllを置き換えることができます。

http://tirania.org/tmp/monotouch.dll

を私がして、バックアップを作成しますケース - 作業中のライブラリで何か問題があった。

関連する問題