2017-05-14 112 views
0

我想向人們保證,當使用按鈕從堆棧彈出控制器時,我已經通過互聯網解釋了所有內容,解釋了內存泄漏,而我意識到UIButton在引發Lambdas事件的同時創建的強大引用。ViewController在Xamarin導航堆棧彈出後沒有被釋放.iOS

我曾嘗試過所有似乎都沒有爲我工作。

問題陳述

我有一個UICollectionViewController爲根視圖控制器和我所編程方式創建並添加爲子視圖在它上面的浮動按鈕。

這些按鈕將視圖控制器推入堆棧。

這裏是我推控制器的方法。

private void HandleClick(object sender, EventArgs e) { 

    var button = sender as UIButton; 
    var board = UIStoryboard.FromName("Main", NSBundle.MainBundle); 
    switch (button.Tag) { 

     case 3: { 
       var vc = board.InstantiateViewController("BibleViewController"); 
       this.NavigationController.PushViewController(vc, true); 
       vc = null; 

       break; 

      } 
     case 5: { 
       var vc = board.InstantiateViewController("RecordingViewController"); 
       this.NavigationController.PushViewController(vc, true); 
       vc = null; 

       break; 
      } 
     case 7: { 
       var vc = board.InstantiateViewController("CameraFbController"); 
       this.NavigationController.PushViewController(vc, true); 
       vc = null; 

       break; 
      } 
     case 6: { 
       var vc = board.InstantiateViewController("NewEmojiController"); 
       this.NavigationController.PushViewController(vc, true); 
       vc = null; 

       break; 
      } 
     case 4: { 
       var vc = board.InstantiateViewController("WriteNShareController"); 
       this.NavigationController.PushViewController(vc, true); 
       vc = null; 
       break; 
      } 
     default : { 
       break; 
      } 



    } 
} 

假設我推BibleViewController(案例3 :)

請找到代碼此控制器

public partial class BibleHomeController : UIViewController 
{ 
    IList<string> items; 
    IList<string> item1; 

    public BibleHomeController() : base("BibleHomeController", null) 
    { 
    } 
    public BibleHomeController(IntPtr handle) : base (handle) 
    { 
    } 
    ~BibleHomeController() { 

     Console.WriteLine("it was called "); 

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

     tableView.DataSource = new BTableViewDataSource(items); 
     tableView.Delegate = new TableDelegate(items,this); 
     tableView.RegisterNibForCellReuse(UINib.FromName("BookCell",NSBundle.MainBundle),BookCell.Key); 




    } 
    public override void ViewWillAppear(bool animated) 
    { 
     base.ViewWillAppear(animated); 
     backBtn.TouchUpInside += HandleBackClick; 
     nwBtn.TouchUpInside += newBtn; 
     oldBtn.TouchUpInside += oldBtnHanle; 
    } 
    private void HandleBackClick(object sender, EventArgs e) 
    { 

     this.NavigationController.PopViewController(true); 
    } 
    public override void ViewWillDisappear(bool animated) 
    { 
     base.ViewWillDisappear(animated); 
     backBtn.TouchUpInside -= HandleBackClick; 
     nwBtn.TouchUpInside -= newBtn; 
     oldBtn.TouchUpInside -= oldBtnHanle; 
        backBtn = null; 
     nwBtn = null; 
     oldBtn = null; 
     tableView = null; 

    } 
    private void newBtn(object sender, EventArgs e) 
    { 

     tableView.DataSource = new BTableViewDataSource(item1); 
     tableView.Delegate = new TableDelegate(item1,this); 
     tableView.ReloadData(); 
    } 
    private void oldBtnHanle(object sender, EventArgs e) 
    { 

     tableView.DataSource = new BTableViewDataSource(items); 
     tableView.Delegate = new TableDelegate(items,this); 
     tableView.ReloadData(); 
    } 
    public override void DidReceiveMemoryWarning() 
    { 
     base.DidReceiveMemoryWarning(); 
     // Release any cached data, images, etc that aren't in use. 
    } 
    private void LoadJson() { 
     using (StreamReader r = new StreamReader("BibleSection/BibleBooks/Books.json")) { 
      string json = r.ReadToEnd(); 
      items = JsonConvert.DeserializeObject<List<string>>(json); 
     } 
     using (StreamReader r = new StreamReader("BibleSection/BibleBooks/NewBook.json")) 
     { 
      string json = r.ReadToEnd(); 
      item1 = JsonConvert.DeserializeObject<List<string>>(json); 
     } 
    } 

} 
public class BTableViewDataSource : UITableViewDataSource 
{ 
    IList<string> data; 

    public BTableViewDataSource(IList<string> list) { 

     data = list; 
    } 
    ~BTableViewDataSource() { 
     Console.WriteLine("it was called "); 
    } 
    public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath) 
    { 
     // if cell is not available in reuse pool, iOS will create one automatically 
     // no need to do null check and create cell manually 
     var cell = (BookCell)tableView.DequeueReusableCell("BookCell", indexPath) as BookCell; 
     cell.PopulateCell(data[indexPath.Row], ""); 
     cell.SetNeedsLayout(); 

     //cell.SeparatorInset = UIEdgeInsets.Zero; 
      return cell; 

    } 

    public override nint RowsInSection(UITableView tableView, nint section) 
    { 

     return data.Count; 

    } 


} 
public class TableDelegate : UITableViewDelegate { 
    IList<string> data; 
    BibleHomeController owner; 
    public TableDelegate(IList<string> list, BibleHomeController reference) 
    { 
     owner = reference; 
     data = list; 
    } 
    ~TableDelegate() 
    { 
    Console.WriteLine("it was called "); 
    } 
    public override void RowSelected(UITableView tableView, NSIndexPath indexPath) 
    { 
     //base.RowSelected(tableView, indexPath); 
     var board = UIStoryboard.FromName("Main", NSBundle.MainBundle); 
     var vc = (BibleChapterCollectionview)board.InstantiateViewController("BibleChapterCollectionview") as BibleChapterCollectionview; 
     vc.itemName = data[indexPath.Row]; 
     owner.NavigationController.PushViewController(vc, true); 

    } 

} 

我的問題是,當我在BibleViewController彈出控制器的 析構沒有任何類被調用,因此不會調用dispose,因此控制器內存不會被釋放。

所以每次我推動和流行我添加一些內存堆。

我想指出,我從viewDidDisappear方法中的按鈕中分離所有事件處理程序。

當我彈出控制器時,請你幫我解釋如何釋放資源。

編輯: 我曾想過問題是與tableview.delegate和table.datasource行。 如果我評論他們的問題解決了。

我應該使用weakDelegate嗎?

回答

1

修改這部分代碼適用於我。

private void HandleBackClick(object sender, EventArgs e) 
    { 
      tableView.Delegate = null; 
      tableView.DataSource = null; 
      tableView.Source = null; 
     this.NavigationController.PopViewController(true); 
    } 

//下面的修改是不相關的問題的陳述,但需要爲按鈕不需要被清零

public override void ViewWillDisappear(bool animated) 
{ 
    base.ViewWillDisappear(animated); 
    backBtn.TouchUpInside -= HandleBackClick; 
    nwBtn.TouchUpInside -= newBtn; 
    oldBtn.TouchUpInside -= oldBtnHanle; 


} 
相關問題