Xamarin内存回收问题
本文关键字:问题 内存 Xamarin | 更新日期: 2023-09-27 17:54:32
我使用Xamarin已经有一段时间了,我遇到了一个非常奇怪的问题。
我能够崩溃一个非常简单的两个屏幕的应用程序。在第一个屏幕上,我有一个UIButton
与TouchUpInside
事件。第二,我有一个UIImageView
附带的图像(从本地文件)。
我所要做的就是一直在这两个视图控制器之间来回移动。
当我连接XCode的仪器与活动监视器上,我注意到我的简单的应用程序达到~100MB的内存回收之前,然后它的使用下降到~15MB。
但是当我循环导航足够长时,内存超过140MB,应用程序崩溃。我在开发一个更复杂的应用程序时发现了这种行为。当然,我正在采取所有可用的预防措施:
- ViewWillDisappear的取消订阅事件
- 取消委托等等。
基本上,在我复杂的应用程序中,我已经覆盖了Dispose
方法在我的所有UIViewControllers
的基类中,我可以看到Dispose
方法被disposing == false
在每个显示的视图控制器上调用。然而,内存使用并没有减少。
有什么问题吗?
我想指出几点:
- My Xamarin Studio是最新的,
- 当我在iPhone 3GS iOS 6.1.3调试模式下测试应用程序时出现崩溃
- 在简单的应用程序中,图像是一个1024x1024的JPG文件。
public partial class SimpleTestViewController : UIViewController
{
private UIButton button;
public SimpleTestViewController () : base ("SimpleTestViewController", null) { }
public override void DidReceiveMemoryWarning ()
{
// Releases the view if it doesn't have a superview.
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
button = new UIButton (new RectangleF(0, 100, 100, 50));
button.BackgroundColor = UIColor.Red;
button.TouchUpInside += (sender, e) => {
this.NavigationController.PushViewController(new SecondView(), true);
};
this.Add (button);
// Perform any additional setup after loading the view, typically from a nib.
}
}
public partial class SecondView : UIViewController
{
private UIImageView _imageView;
public SecondView () : base ("SecondView", null) { }
public override void DidReceiveMemoryWarning ()
{
// Releases the view if it doesn't have a superview.
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
_imageView = new UIImageView (new RectangleF(0,0, 200, 200));
_imageView.Image = UIImage.FromFile ("Images/image.jpg");
this.Add (_imageView);
// Perform any additional setup after loading the view, typically from a nib.
}
protected override void Dispose (bool disposing)
{
System.Diagnostics.Debug.WriteLine("Disposing " +this.GetType()
+ " hash code " + this.GetHashCode()
+ " disposing flag "+disposing);
base.Dispose (disposing);
}
}
您正在创建按钮/图像的实例并将它们存储在后台字段中,并且您没有在控制器的Dispose
中对它们调用Dispose
。控制器实例化了它们,所以你必须清除它们。
在上面的例子中,您也没有解除按钮TouchUpInside
事件的连接。我建议不要为此使用lambda,而是为它创建一个方法,以便稍后更容易分离。
TouchUpInside -= this.Method;
另外,您没有从添加到的视图中删除图像。
我知道你说你在视图中做这些事情,它会消失,但这不会发生在你的示例代码中。你能提供一个完整的例子吗?