9

Mono GC と ObjC 参照カウントがどのように共存しているかを理解することに近づいていると思います。

そのしくみは、ネイティブ オブジェクトの参照カウントが 1 の場合、マネージド インスタンスがガベージ コレクションされるのを妨げないということです。参照カウントが 1 を超えるとすぐに、マネージド インスタンスがガベージ コレクションされないようにします。

これは、管理対象オブジェクトにユーザー状態が含まれる場合があるためです。対応するネイティブ オブジェクト (マネージド UIView インスタンスなど) をミラーリングしているマネージド オブジェクトの場合、MonoTouch はインスタンスに状態を含めることができないことを認識しているため、マネージド コードがマネージド インスタンスへの参照を持たなくなるとすぐに、GC はそれを収集できます。後の段階でマネージド インスタンスが必要になった場合は、新しいインスタンスを作成するだけです。

したがって、CustomButtonを継承するを作成し、UIButtonそれをサブビューとして に追加しView、マネージド参照をスコープから外してから GC を実行すると、このマネージドは CustomButtonまだコレクションの対象になりません。

なぜ収集できないのですか?もちろん、プロパティのような管理された状態を持っているかもしれませんが、管理されたオブジェクトからのリンクがなければ、誰がこの状態を気にするでしょうか? 消えるだけかもしれませんが、なぜ消えないのでしょうか?

考えられる理由の 1 つを考えています。CustomButtonイベントをサブスクライブしても GC が存続しないため、オブジェクトが収集されると、イベントの発生が停止します。これにより、予期しない動作が発生する可能性があります。

これは正しいです?誰もリンクしていない場合でも、管理対象オブジェクトを存続させる他の理由はありますか?

4

1 に答える 1

8

なぜ収集できないのですか?もちろん、プロパティのような管理された状態を持っているかもしれませんが、管理されたオブジェクトからのリンクがなければ、誰がこの状態を気にするでしょうか? 消えるだけかもしれませんが、なぜ消えないのでしょうか?

ネイティブ コードにはオブジェクトへの参照が含まれている可能性があり、これにより、後でオブジェクトがマネージド コードに再表示される可能性があります。

コードサンプルは何が起こるかを示していると思います:

class MyView : UIView {
    public string ImportantSecret;
}

class AppDelegate : UIApplicationDelegate {
    UIViewController vc;
    public override bool FinishedLaunching (UIApplication app, 
                                            NSDictionary options)
    {
        var myView = new MyView ();
        myView.ImportantSecret = "MonoTouchRocks";

        vc = new UIViewController ();
        vc.View = new UIView ();
        vc.View.AddSubView (myView);

        // When this method returns the only place where myView is referenced
        // is from inside the *native* Subviews collection.

        BeginInvokeOnMainThread (() =>
        {
            Console.WriteLine (((MyView) vc.Subviews [0]).ImportantSecret);
            // If the MyView instance was garbage collected and recreated
            // automatically at this point, ImportantSecret would be null.
        });
    }
}

重要: このコードは、GC が状態を持つ管理対象オブジェクトを収集できない理由を説明するためのものです。Subviews 配列はマネージ コードに自動的にキャッシュされるため、この特定のサンプルでは実際には重要な秘密を忘れることはありませんが、一般的にはそうではありません。

于 2012-10-25T09:02:22.037 に答える