Xamarin UITableViewCell内存泄漏

时间:2015-02-12 20:46:58

标签: uitableview xamarin

我使用Xamarin和继承UITableViewController,UITableViewSource和UITableViewCell的类来提供简单的项目列表。 我发现一旦垃圾收集运行,就会收集到UITableViewController和UITableViewSource,但是UITableViewCell永远不会被正确处理和收集。

这是我的示例代码。

public class Test1ButtonCell : UITableViewCell
{
    public static readonly NSString Key = new NSString("Test1ButtonCell");

    public Test1ButtonCell () : base (UITableViewCellStyle.Default, Key)
    {
        TextLabel.TextColor = UIColor.Black;
        TextLabel.TextAlignment = UITextAlignment.Left;
    }

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

public class Test1Controller : UITableViewController
{
    private WeakReference<Test1Source> source = null;


    public Test1Controller () : base (UITableViewStyle.Grouped)
    {
    }

    public override void DidReceiveMemoryWarning ()
    {
        base.DidReceiveMemoryWarning ();
    }

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();

        List<String> testdata = new List<String>( );
        for( int i = 0; i < 30; i++ )
        {
            testdata.Add( i.ToString( ) );
        }


        source = new WeakReference<Test1Source>(new Test1Source( this,testdata ));

        testdata = null;

        this.NavigationItem.LeftBarButtonItem = new UIBarButtonItem  ("Back", UIBarButtonItemStyle.Plain, null);
    }

    public override void ViewWillAppear(bool animated)
    {
        base.ViewWillAppear (animated);

        this.NavigationItem.Title="Test1";

        TableView.Source = source.target;

        this.NavigationItem.LeftBarButtonItem.Clicked += HandleBackButtonTouch;

    }
    public override void ViewWillDisappear (bool animated)
    {
        this.NavigationItem.LeftBarButtonItem.Clicked -= HandleBackButtonTouch;

        base.ViewWillDisappear (animated);

        TableView.Source = null;
    }


    private void HandleBackButtonTouch(object sender, EventArgs e)
    {
        NavigationController.PopToRootViewController( true );
    }

    protected override void Dispose (bool disposing) 
    { 

        base.Dispose (disposing); 
    } 

}

public class Test1Source : UITableViewSource
{
    private WeakReference<Test1Controller> controller;

    private List<String> testdata = new List<string>();


    public Test1Source (Test1Controller controller, List<String> testData)
    {
        testdata = testData;
        this.controller = new WeakReference<Test1Controller>( controller );
    }

    public override nint NumberOfSections (UITableView tableView)
    {
        return 1;
    }

    public override nint RowsInSection (UITableView tableview, nint section)
    {
        if( section == 0 )
        {
            return testdata.Count;
        }
        else
        {
            return 0;
        }
    }

    public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
    {

        var cell = tableView.DequeueReusableCell (Test1ButtonCell.Key) as Test1ButtonCell;
        if( cell == null )
        {
            cell = new Test1ButtonCell( );
        }

        if( indexPath.Section == 0 )
        {
            cell.TextLabel.Text = testdata[ indexPath.Row ];
        }

        return cell;
    }

}

2 个答案:

答案 0 :(得分:0)

UITableView缓存(并重用)UITableViewCells。

一旦UITableView被释放,他们就会离开。

答案 1 :(得分:0)

我可以确认问题。它在模拟器上正常工作,而不在设备上。

我唯一能想到的是保留所有已创建的自定义单元格的某个列表(通过将它们添加到单元格的构造函数中的列表中)并在处理表格时将其置于其中。有点丑,但它确实有效。