Reputation: 89
I have a function that gets called several times in a loop and returns a view controller( each view controller is like a slide of a presentation ). Uiviewcontroller has subviews like scroll view , uiwebview and uiimageview. As the number of view controllers increase, i get memory warnings and app crashes. I have wrapped the function in a nsautorelease pool and i am using "using" block to dispose the uiimages but no use.
Can you look at the code and tell me whats wrong and how i can solve the memory problem.
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;
}
Upvotes: 1
Views: 1351
Reputation: 5234
The question is why are you creating multiple view controllers with the same view (different content)? Why not create a single view controller and then change the content of it on ViewDidLoad()? I don't see you using the passed integer anywhere so is this your actual code or just a sample of what you are doing?
If you want to change the content of the controller without reloading, create a function to change the values. For example:
public void Bind(UIImage image)
{
this.imgView.Image = image;
}
Upvotes: 1
Reputation: 33048
Using NSAutoReleasePool
won't help you, neither will disposing the image or image view help you (In fact, your code disposes the UIImageView
you're adding to the UIScrollView
- I'm actually wondering why this is working at all).
If you are creating tons of instances of a UIViewController
that hosts a lot of subviews and especially large images, you will eventually run out of memory as long as you reference these controllers from somewhere.
From what I see, your image is 1024x768, probably at 32bit color depth, that's 3 megabyte per image in memory.
You will have to get rid of the view controller's you're creating or make them smarter (load and dispose the images in ViewWillAppear()
and ViewWillDisappear()
for instance)
Upvotes: 2