[英]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.