2016-12-19 19 views
1

私のアプリでは、Xamarin Profilerを使用して、VCをスタックにプッシュして戻ってくると、メモリ割り当ては空き状態ではないことに気付きました。同じビューをもう一度押すと、メモリが増えます。メモリを解放しないで戻る

テストするサンプルプロジェクトを作成しましたが、同じことがわかりました。

サンプル・プロジェクト:

私は2つのビューコントローラ、VC1とVC2を持っています。 VC1はルートビューコントローラです。

VC1をVC1から押し込むと、メモリが割り当てられますが、逆にナビゲートするとメモリは解放されません。 VC2をもう一度押すと、メモリが増えます。 VC2では、3つのラベルをデザイナーに追加しました。 AppDelegateで

namespace TestSample 
{ 
    [Register("AppDelegate")] 
    public class AppDelegate : UIApplicationDelegate 
    { 
     public override UIWindow Window 
     { 
      get; 
      set; 
     } 

     public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) 
     { 
      Window = new UIWindow(UIScreen.MainScreen.Bounds); 
      var nav = new UINavigationController(new MyViewController()); 
      Window.RootViewController = nav; 
      Window.MakeKeyAndVisible(); 

      return true; 
     } 
    } 
} 

VC1:

namespace TestSample 
{ 
    public partial class MyViewController : UIViewController 
    { 
     public MyViewController() : base("MyViewController", null) 
     { 
     } 

     public override void ViewDidLoad() 
     { 
      base.ViewDidLoad(); 
      // Perform any additional setup after loading the view, typically from a nib. 
     } 
     public override void ViewWillAppear(bool animated) 
     { 
      base.ViewWillAppear(animated); 

      btn1.TouchUpInside += Btn1_TouchUpInside; 
     } 

     void Btn1_TouchUpInside(object sender, EventArgs e) 
     { 
      NavigationController.PushViewController(new MyViewController2(), true); 
     } 

     public override void ViewDidDisappear(bool animated) 
     { 
      base.ViewDidDisappear(animated); 
      btn1.TouchUpInside -= Btn1_TouchUpInside; 
     } 

     public override void DidReceiveMemoryWarning() 
     { 
      base.DidReceiveMemoryWarning(); 
      // Release any cached data, images, etc that aren't in use. 
     } 
    } 
} 

VC2:Xamarin.iOSで

namespace TestSample 
{ 
    public partial class MyViewController2 : UIViewController 
    { 
     public MyViewController2() : base("MyViewController2", null) 
     { 
     } 

     public override void ViewDidLoad() 
     { 
      base.ViewDidLoad(); 
      // Perform any additional setup after loading the view, typically from a nib. 
     } 

     public override void DidReceiveMemoryWarning() 
     { 
      base.DidReceiveMemoryWarning(); 
      // Release any cached data, images, etc that aren't in use. 
     } 

     public override void ViewDidDisappear(bool animated) 
     { 
      base.ViewDidDisappear(animated); 
      /*foreach (UIView view in View.Subviews) { 
       view.RemoveFromSuperview(); 
      }*/ 

      label1.RemoveFromSuperview(); 
      label2.RemoveFromSuperview(); 
      label3.RemoveFromSuperview(); 

      label1.Dispose(); 
      label2.Dispose(); 
      label3.Dispose(); 
     } 
    } 
} 
+0

VC2を投稿できますか?ここに循環参照があり、何かをヌルに設定するか、またはDispose()を呼び出すことによって関係を切断する必要があります。そうしないと、GCはコレクションに適格なオブジェクトを決して見ません。 –

+0

VC2には、デザイナーを介してXIBファイルに追加したラベルが3つしかありません。編集されたVC2 – PLOW

+0

@PLOW 'GC.Collect()'を強制するとメモリが解放されますか? – SushiHangover

答えて

5

ガベージコレクションは全く壊れていません。 GCを使用すると、メモリー消費と(強力な)参照に注意する心配がなくなるという一般的な誤解(どのシステムでも!)があります。

X.iOSは、参照カウントされた世界の上に位置し、これには一定の測定が必要です。これはすべて文書化されています。はい、すべてのニュアンスを理解するのは難しいかもしれません。

私はあなたの例を試してみましたが、VC2は期待どおりに集められました(FinalizerとDispose()が呼び出されます)。また、Profiler(1.0.2-2)には漏れはありません。

2つのXIBベースのコントローラを作成し、ボタンを最初の1つに追加し、3つのラベルを2番目のボタンに追加しました。ラベルを削除または廃棄する必要はなく、最初のVCのクリックイベントから退会する必要もありません。

プロジェクトの動作が異なる場合は、VC2への参照をどこかに保持しています。多分あなたは完全なプロジェクトを提供することができます、そして、私はそれを見ることができます。

関連する問題