如何打破视图控制器和数据源之间的引用循环

考虑这个简单的例子:

public partial class TableViewController : UITableViewController { public TableViewController (IntPtr handle) : base (handle) { } protected override void Dispose (bool disposing) { Console.WriteLine (String.Format ("{0} controller disposed - {1}", this.GetType (), this.GetHashCode ())); base.Dispose (disposing); } public override void ViewDidLoad () { //TableView.Source = new TableSource(this); TableView.Source = new TableSource(); } } public class TableSource : UITableViewSource { private TableViewController controller; string CellIdentifier = "TableCell"; public TableSource () { } public TableSource (TableViewController controller) { this.controller = controller; } public override nint RowsInSection (UITableView tableview, nint section) { return 1; } public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) { UITableViewCell cell = tableView.DequeueReusableCell (CellIdentifier); //if there are no cells to reuse, create a new one if (cell == null){ cell = new UITableViewCell (UITableViewCellStyle.Default, CellIdentifier); } cell.TextLabel.Text = "test"; return cell; } } 

我注意到视图控制器(TableViewController)从未发布过。 表视图控制器具有对数据源的引用,但数据源也具有对表视图控制器的引用。

使用TableView.Source = new TableSource(); 视图控制器被释放,使用TableView.Source = new TableSource(this); 不是。

该参考周期应如何打破,以便一切都被释放?

编辑:

现在我尝试了WeakReference

通过使用WeakReference ,当视图控制器从导航堆栈弹出时,将调用Dispose方法。

ViewDidLoad

 TableView.Source = new TableSource(new WeakReference (this)); 

在数据源中:

 private WeakReference controller; public TableSource (WeakReference controller) { this.controller = controller; } 

我将它构建到我的真实项目中,但是如何访问我的控制器 ? 我收到了消息

类型’System.WeakReference’不包含’xxx’的定义,也没有找到’System.WeakReference’类型的扩展方法’xxx’。 你错过了assembly参考吗?

你看,你和Xamarin一起工作? 你试过WeakReference吗? https://msdn.microsoft.com/en-us/library/system.weakreference(v=vs.110).aspx

PS:

 private WeakReference weakController; 

设置:

 this.weakController = new WeakReference(controller); 

要得到:

 if (weakController.isAlive) { TableViewController controller = weakController.Target as TableViewController; } 

更改

 public partial class TableViewController : UITableViewController 

 public partial class TableViewController : UITableViewController, UITableViewSource 

而在ViewDidLoad中就是这么做的

 self.TableView.Source = self; 

source属性在内部已经是一个弱引用所以你没有管理它的问题。 将tbaleviewcontroller作为委托和数据源完全是一个方便的属性。 (就像在原生iOS中一样)

您可以将方法移动到控制器本身,这比WeakReference更麻烦。 然后使用export属性标记它们,然后允许您将UITableView.WeakDataSource属性设置为控制器本身。

 [Export("tableView:numberOfRowsInSection:")] public nint RowsInSection (UITableView tableview, nint section) [Export("tableView:cellForRowAtIndexPath:")] public UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) 

移动后,您可以附加数据源:

 public override void ViewDidLoad () { TableView.WeakDataSource = this; }