3

c# Xamarin で、iOS がテーブル ビューに使用する「デリゲート」または「データ ソース」パターンに相当するものを実装するにはどうすればよいですか? たとえば、次のようなビュー クラスが必要です。

public class MyDataView : UIView
{
  public interface ISource
  {
    int NumberOfPages();
  }

  public ISource DataSource { get; set; }
}

しかし問題は、次のようなコードで MyViewController からこれを呼び出すときです。

this.myDataView.DataSource=new ViewSource(this)

public class ViewSource : MyDataView.ISource
{
  private readonly MyViewController parentController;

  public ViewSource(MyViewController parentController)
  {
    this.parentController=parentController;
  }
}

循環参照が作成されるため、 MyViewController をガベージ コレクションすることはできません。

これは一般的な要件のように思えますが、人々はどのようなデザインを使用しているのでしょうか?

ソースを弱参照にする必要がありますか? それはC#でどのように行われますか? 呼び出し元が弱い参照であることを知らない可能性があるので、それは危険ではありませんか?

4

3 に答える 3

2

プロファイラーを使用して、それが本当にメモリ リークであるかどうかを確認することをお勧めします。それが本当に問題であることがわかった場合は、オブジェクトへの弱参照を保持するWeakReferenceclassを使用してデリゲートを弱参照することができます。

于 2013-09-03T16:04:02.917 に答える
0

私は個人的に、MonoTouch での放棄されたメモリにしばしば苦労しました。私が今やっていることは、Dispose() を呼び出し、目的の c レイヤーに存在するすべてのオブジェクトを null に設定することです。

public class AView : UIView {

    private UIView tip;
    private UIView top;

    protected override void Dispose(bool disposing) {
        base.Dispose(disposing);
        this.ReleaseDesignerOutlets();

        if (this.tip != null) {
            this.tip.Dispose();
            this.tip = null;
        }

        if (this.top != null) {
            this.top.Dispose();
            this.top = null;
        }
    }

}

「dealloc」が Dispose() メソッドにバインドされているとは思いません。これは、マネージド オブジェクトがマネージド環境で GC によって収集されたときにのみ呼び出されるためです。ネイティブ オブジェクトが消滅するという意味ではなく、管理された環境でそのオブジェクトへの参照がないことを意味するだけです。マネージド環境でネイティブ オブジェクトが表示される場合、Mono ランタイムはネイティブ オブジェクトにバインドするマネージド オブジェクトを作成 (または作成済みのオブジェクトを再利用) し、後者の参照カウンターを増やします。GC が管理対象オブジェクトを収集すると、参照カウンターが減少します。ただし、Dispose() メソッドが呼び出されない場合は、GC がオブジェクトを収集しなかったため、オブジェクトには少なくとも 1 の参照カウンターがまだ残っていることを意味します。

これから私が言おうとしていることは、私が今言ったことに対して少し矛盾するでしょう. Mono ランタイムでは、GC されたオブジェクトを C# の世界に再び出現させることはできないと思います (空状態の不思議な新しい C# オブジェクトは必要ありませんよね?)。したがって、マネージド環境でオブジェクトへの参照がなくても、ref カウンターがちょうど 1 になるまで、実際にはオブジェクトをガベージ コレクションしません。したがって、GC がオブジェクトを収集すると、それらは実際にはメモリから解放されます。

あなたの場合(私が思うに)起こっていることは、ViewがViewControllerへの参照を保持するDataSourceへの参照を保持していることです。View はそれへの参照を保持しているため、ViewController は GC されません。この View を指す参照がなくても、オブジェクトの参照カウントがまだ 2 であるため、GC はそれを収集しません。実際、ネイティブの世界の ViewController はまだこのビューへの参照です。

于 2013-08-31T21:42:17.193 に答える