向后导航不会释放内存

时间:2016-12-19 22:27:27

标签: c# memory-management xamarin xamarin.ios

在我的应用程序上,使用Xamarin Profiler我注意到每当我将VC推送到堆栈并导航回来时,内存分配就不是免费的。如果我再次推送相同的视图,则会增加更多内存。

我创建了一个要测试的示例项目,我发现这是同样的事情。

示例项目:

我有两个视图控制器,VC1和VC2。 VC1是根视图控制器。

每当我从VC1推送VC2时,都会分配内存,但是当我向后导航时,内存不是空闲的。如果我再次继续推动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:

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

1 个答案:

答案 0 :(得分:5)

Xamarin.iOS中的垃圾收集根本没有被破坏。这是一个普遍的误解(在任何系统上!)有一个GC意味着人们不必担心对内存消耗和(强)引用的关注。

X.iOS位于参考计数世界的顶部,这需要进行某些测量。所有这些都记录在案;是的,很难理解所有的细微差别。

那就是说:我尝试了你的例子,并按预期收集了VC2(Finalizer和Dispose()被调用)。此外,Profiler(1.0.2-2)也没有显示任何泄漏。

我创建了两个基于XIB的控制器,并为第一个添加了一个按钮,为第二个添加了一个标签。您不必删除或处置任何标签,也不必取消订阅您案例中第一个VC中的click事件。

如果您的项目行为不同,则会在某处保留对VC2的引用。也许你可以提供完整的项目,然后我可以看看它。

相关问题