2017-05-14 9 views
0

스택에서 컨트롤러를 팝하는 데 버튼을 사용할 때 메모리 누수에 대해 설명하는 인터넷을 통해 모든 기사를 읽었 음을 사람들에게 확신시키고 싶습니다. UIButton이 Lambdas와 함께 이벤트를 트리거하는 동안 생성하는 강력한 참조를 인식합니다.ViewController가 Xamarin.iOS의 네비게이션 스택에서 팝핑 된 후에 공개되지 않습니다.

나는 나를 위해 일하는 것 같지 않은 모든 것을 시도했다.

문제 문

나는 루트의 ViewController로 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 :

내가 BibleViewController에서 컨트롤러를 팝업 할 때

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); 

    } 

} 

내 문제가있다이 컨트롤러의 소멸자에 대한 코드를 찾아주세요 가정 어떤 클래스도 호출되지 않아 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; 


}