2016-12-19 6 views
1

В моем приложении, используя Xamarin Profiler, я заметил, что всякий раз, когда я нажимаю VC в стек и перемещаюсь назад, выделение памяти не является бесплатным. Если я снова нажму тот же вид, он добавит больше памяти.Перемещение назад не освобождает память

Я создал образец проекта для тестирования, и я узнал, что это делает то же самое.

Пример проекта:

У меня есть два вид контроллеров, VC1 и VC2. VC1 - это контроллер корневого представления.

Всякий раз, когда я нажимаю VC2 из VC1, выделяется память, но когда я перехожу назад, память не является свободной. Если я продолжаю нажимать VC2 снова, он добавляет больше памяти. В VC2 я добавил три этикетки через дизайнера.

в 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:

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? У вас есть круговая ссылка здесь, и отношения нужно отделить, установив что-то в null или вызывая 'Dispose()', иначе GC никогда не увидит объект, подходящий для сбора. –

+0

VC2 имеет только 3 метки, которые я добавил через конструктор в файле XIB. Отредактированный VC2 – PLOW

+0

@PLOW Если вы вынудите 'GC.Collect()' его память восстановлена? – SushiHangover

ответ

5

Сбор мусора в Xamarin.iOS не нарушается на всех. Это общее заблуждение (на любой системе!), Что наличие GC означает, что вам не нужно беспокоиться о том, чтобы больше заботиться о потреблении памяти и (сильных) ссылках.

X.iOS находится на вершине подсчитанного мира, и для этого требуются определенные измерения. Все это документировано; и да, это может быть трудно понять все нюансы.

Это сказало: я попробовал ваш пример, и VC2 собран как ожидалось (Finalizer и Dispose() называются). Также Profiler (1.0.2-2) не обнаруживает утечек.

Я создал два контроллера на базе XIB и добавил кнопку для первой и трех меток ко второй. Вам не нужно удалять или удалять любые ярлыки, и вам не нужно отказаться от подписки на событие click в первом VC в вашем случае.

Если ваш проект ведет себя по-другому, вы где-то сохраняете ссылку на VC2. Возможно, вы можете предоставить полный проект, тогда я могу взглянуть на него.

Смежные вопросы