我有一个在循环中多次调用的函数并返回一个视图控制器(每个视图控制器就像一个演示文稿的幻灯片)。 Uiviewcontroller有子视图,如滚动视图,uiwebview和uiimageview。随着视图控制器数量的增加,我得到内存警告和应用程序崩溃。我已将该函数包装在nsautorelease池中,并且我使用“using”块来处理uiimages但没有用。
你能看一下代码并告诉我什么是错的以及如何解决内存问题。
public UIViewController GetPage(int i){
using (var pool = new NSAutoreleasePool ()) {
UIViewController c = new UIViewController ();
c.View.Frame = new RectangleF (0, 0, 1024, 743);
UIScrollView scr = new UIScrollView (new RectangleF (0, 0, 1024, 743));
scr.ContentSize = new SizeF (1024, 748);
string contentDirectoryPath = // path string
UIWebView asset = new UIWebView (new RectangleF (0, 0, 1024, 748));
asset.ScalesPageToFit = true;
UIScrollView scrl = new UIScrollView (new RectangleF (0, 0, 1024, 748));
scrl.ContentSize = new SizeF (1024, 768);
using (UIImageView imgView = new UIImageView (new RectangleF (0, 0, 1024, 748))) {
using (var img = UIImage.FromFile (contentDirectoryPath)) {
imgView.Image = img;
img.Dispose ();
}
//UIImage img = UIImage.FromFile (contentDirectoryPath);
//imgView.Image = img;
imgView.ContentMode = UIViewContentMode.ScaleAspectFit;
float widthRatio = imgView.Bounds.Size.Width / imgView.Image.Size.Width;
float heightRatio = imgView.Bounds.Size.Height / imgView.Image.Size.Height;
float scale = Math.Min (widthRatio, heightRatio);
float imageWidth = scale * imgView.Image.Size.Width;
float imageHeight = scale * imgView.Image.Size.Height;
imgView.Frame = new RectangleF (0, 0, imageWidth, imageHeight);
scrl.AddSubview (imgView);
imgView.Center = imgView.Superview.Center;
imgView.Dispose ();
}
asset.AddSubview (scrl);
scrl.Center = scrl.Superview.Center;
asset.ScalesPageToFit = true;
scr.AddSubview (asset);
c.View.AddSubview (scr);
scr.Center = scr.Superview.Center;
return c;
}
答案 0 :(得分:2)
使用NSAutoReleasePool
对您没有帮助,处理图片或图片视图也不会帮助您(事实上,您的代码会处理您UIImageView
添加的UIScrollView
- 我实际上想知道为什么这一切都在起作用。)
如果要创建大量的UIViewController
实例,其中包含大量子视图,特别是大图像,只要您从某处引用这些控制器,最终就会耗尽内存。
从我看到的情况来看,你的图像是1024x768,可能是32位色深,即内存中每张图像3兆字节。
您必须摆脱正在创建的视图控制器或使其更智能(例如,在ViewWillAppear()
和ViewWillDisappear()
中加载和处理图像)
答案 1 :(得分:1)
问题是为什么要创建具有相同视图(不同内容)的多个视图控制器?为什么不创建一个视图控制器,然后在ViewDidLoad()上更改它的内容?我没有看到你在任何地方使用传递的整数,所以这是你的实际代码还是你正在做的样本?
如果要在不重新加载的情况下更改控制器的内容,请创建一个更改值的函数。例如:
public void Bind(UIImage image)
{
this.imgView.Image = image;
}