简体   繁体   中英

Navigating back does not free memory

On my app, using Xamarin Profiler I noticed that whenever I push a VC to the stack and navigate back the memory allocation is not free. If I push that same view again it adds more memory.

I created a sample project to test and I found out that is does the same thing.

Sample project:

I have two view controllers, VC1 and VC2. VC1 is the root view controller.

Whenever I push VC2 from VC1, memory is allocated but when I navigate back the memory is not free. If I keep pushing VC2 again it adds more memory. In VC2 I added 3 labels through the designer.

in 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();
        }
    }
}

Garbage Collection in Xamarin.iOS is not broken at all. It is a general misconception (on any system!) that having a GC means one does not have to worry about being careful about memory consumption and (strong) references anymore.

X.iOS sits on top of a reference counted world and this requires certain measurements being taken. All of this is documented; and yes, it can be hard to understand all the nuances.

That said: I tried your example and VC2 is collected as expected (Finalizer and Dispose() are called). Also the Profiler (1.0.2-2) does not show any leaks.

I created two XIB based controllers and added a button to the first one and three labels to the second one. You don't have to remove or dispose any labels, nor do you have to unsubscribe from the click event in the first VC in your case.

If your project behaves differently you are keeping a reference to VC2 somewhere. Maybe you can provide the complete project, then I can have a look at it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM