2010-10-13 23 views
2

我在iPhone應用程序中遇到內存問題。我正在使用MonoTouch。我通過使用靜態實例計數器來追究這個問題。這個問題與模態視圖控制器有關。當我從根視圖控制器導航到第一級視圖控制器並返回時,我發現第一級視圖控制器是垃圾收集的。但是當我通過調用PresentModalViewController來製作第一級viewcontroller模式時,我通過調用DismissModalViewControllerAnimated返回,我發現第一級viewcontroller不是垃圾收集。即使我打電話給GC.Collect()UIViewController在啓動模式時不會收集垃圾

爲什麼不呢?難道我做錯了什麼?

確保視圖控制器發佈的最佳做法是什麼?

partial class RootViewController : UITableViewController 
{ 
    static int instanceCount; 
    static int nextId; 
    int instanceId; 

    public RootViewController (IntPtr handle) : base(handle) 
    { 
     instanceCount++; 
     instanceId = nextId++; 
     Console.WriteLine(string.Format("RootViewController #{0} Count={1}", instanceId, instanceCount)); 
    } 

    public override void ViewDidLoad() 
    { 
     base.ViewDidLoad(); 
     Title = "Root"; 
     NavigationItem.RightBarButtonItem = new UIBarButtonItem("ModalVC", UIBarButtonItemStyle.Plain, 
      delegate 
      { 
       var firstlevelVc = new FirstLevelViewController(); 
       PresentModalViewController(new UINavigationController(firstlevelVc), true); 
      }); 

     NavigationItem.LeftBarButtonItem = new UIBarButtonItem("PushVC", UIBarButtonItemStyle.Plain, 
      delegate 
      { 
       var firstlevelVc = new FirstLevelViewController(); 
       NavigationController.PushViewController(firstlevelVc, true); 
      }); 
    } 

    public override void ViewDidAppear (bool animated) 
    { 
     base.ViewDidAppear (animated); 
     GC.Collect(); 
    } 

    ~RootViewController() 
    { 
     instanceCount--; 
     Console.WriteLine(string.Format("RootViewController #{0} Count={1}", instanceId, instanceCount)); 

    } 
} 
public partial class FirstLevelViewController : UIViewController 
{ 
    static int instanceCount; 
    static int nextId; 
    int instanceId; 
    public FirstLevelViewController (IntPtr handle) : base(handle) 
    { 
     Initialize(); 
    } 

    [Export("initWithCoder:")] 
    public FirstLevelViewController (NSCoder coder) : base(coder) 
    { 
     Initialize(); 
    } 

    public FirstLevelViewController() : base("FirstLevelViewController", null) 
    { 
     Initialize(); 
    } 

    void Initialize() 
    { 
     instanceCount++; 
     instanceId = nextId++; 
     Console.WriteLine(string.Format("FirstLevelViewController #{0} Count={1}", instanceId, instanceCount)); 
    } 

    public override void ViewDidLoad() 
    { 
     base.ViewDidLoad(); 
     Title = "1. level"; 

     NavigationItem.RightBarButtonItem = new UIBarButtonItem("Dismiss modal", 
                   UIBarButtonItemStyle.Plain, 
                   delegate { ParentViewController.DismissModalViewControllerAnimated(true); }); 

    } 

    ~FirstLevelViewController() 
    { 
     instanceCount--; 
     Console.WriteLine(string.Format("FirstLevelViewController #{0} Count={1}", instanceId, instanceCount)); 

    } 
} 
+0

我不能複製這個,但我沒有你的xibs或調用代碼。您可以向我發送整個項目,或者在http://monotouch.net/Support上提交錯誤消息嗎? – 2010-11-04 15:09:08

回答

0

終結(〜方法)當一個對象引用計數器變爲0被調用,你確定你沒有一個參考的地方給你使用的UIViewController?爲了確保我沒有引用並確保刪除GC,我實現了IDisposable和Dispose方法,調用它並在那裏進行必要的清理(從內部集合等中刪除所有對象),然後設置原始變量爲空。所以它看起來像:

MyUIViewController cntrl = new MyUIViewController();

...做一些東西

//完成 cntrl.Dispose時(); cntrl = null;

就是這樣。

順便說一句。我相信你不應該經常自己調用GC.Collect,因爲它會停止所有線程並只進行清理,所有工作都會停止,並且資源非常繁重。

希望它有幫助。

+0

如果存在對FirstLevelViewController的引用,它可能來自使用語句PresentModalViewController(new UINavigationController(firstlevelVc),true)創建的UINavigationController。但據我所見,navigationcontroller無法訪問。 – 2010-10-13 21:58:13

+0

我只使用終結器來實現實例計數和跟蹤,我只使用GC.Collect()來證明我的觀點。 – 2010-10-13 21:58:48

+1

而你如何解僱模態控制器?該模板將使用this.ParentViewController.DismissModalViewControllerAnimated從子控件調用它到頂層控件。稱它爲自己的孩子,可能會導致這種情況。只是一個想法。 – 2010-10-13 22:13:04

0

如果您想手動處置控制器,您可以調用Dispose。