簡體   English   中英

如何在c#Xamarin中實現ios委托/數據源模式?

[英]How to implement the ios delegate / data source pattern in c# Xamarin?

如何在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永遠不會被垃圾收集。

這似乎是一個常見的要求,那么人們使用什么樣的設計呢?

我應該將Source作為弱參考嗎? 怎么在c#中完成? 並不是那么危險,因為來電者可能不知道它的弱引用?

我建議你使用Profiler來查看這是否真的是內存泄漏。 如果您發現它確實是一個問題,您可能會使用WeakReference弱引用該委托, 該類包含對象的弱引用。

垃圾收集器非常能夠處理循環引用。 你不必擔心它。

我個人經常在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的ref計數器。

我現在要說的是與我剛才所說的相矛盾。 我認為Mono Runtime不允許GCed對象再次浮出水面進入C#World(我們不希望神秘的新C#對象具有空狀態嗎?)。 因此,即使對象在托管環境中沒有引用它,它們實際上也不會垃圾收集對象,直到ref計數器正好為1。 因此,當GC收集對象時,它們實際上是從內存中釋放的。

在你的情況下(我認為)正在進行的是View保存對DataSource的引用,該DataSource包含對ViewController的引用。 ViewController不是GCed,因為View保存了對它的引用,即使沒有引用指向此View,GC也不會收集它,因為該對象的引用數仍為2.實際上,本機中的ViewController具有仍然是對這種觀點的參考。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM