views:

87

answers:

2

Hi -

I am having a problem with memory I cant get straightened out. What I am doing is this:

I have a viewcontroller that looks similar to a book with 7 different tabs. Each time the user presses a tab, the content on the "page" changes and the background image changes to reflect the different tab selected. Each background image is 768x1024 and there is one for each of the 7 tabs.

My problem is that when each tab is selected, the memory is never released for the previous image, and after 7 tabs are selected I have something like 30MB being used up for 7 different images. I have 7 different methods for each of the 7 tabs that the user presses.

-(IBAction) pressedTab1 {

    self.tabsImageView.image = nil; //tabsImageView is the imageView I am keeping he background image in.
    UIImage *tempUIImage = [UIImage imageNamed:@"tab1selected.png"]; 

    self.tabsImageView.image = tempUIImage;


}
+1  A: 

You can just assign the image directly like this. And because [UIImage imageNamed...] is autorelease, the memory will be handled for you.

-(IBAction) pressedTab1 {
  self.tabsImageView.image = [UIImage imageNamed:@"tab1selected.png"];
}
djones
this isn't doing it unfortunately. My allocations still jump up by about 4MB each time I select a tab.
Brodie
The issue must be somewhere else in your code - because that won't leak. [UIImage imageNamed...] is very good at autoreleasing memory and caching your image too if you use it multiple times.
djones
Thanks - if it helps at all, it only jumps up the first time the image is loaded. once I have opened all 7 tabs, the memory usage stays the same.
Brodie
Keep in mind that even though you are using PNG image files, they are stored in memory as bitmaps, so they'll take up signifigsntly more memory than they do on disk.
kubi
Yep, that makes sense. I think that is because of the caching.What you might wanna do is define these images on the class itself and initialise them on the init(). That way you have a class-wide handle on them if you want to set them back to nil.The issue with your code above is that you're creating a new image every time and not keeping a proper handle on the previous one so when you set it back to nil you're not actually releasing the image you think you are.
djones
If they only thing you are using them for is the background on a view, try resizing them to fit the resolution of the iPhone.
kubi
Yes I undestand that, each png is only 8kb, and a bitmap would be about 3.1MB, which is just about how much my allocations go up each time I load a new tab.
Brodie
kubi - it's an iPad app so they are already as small asI can get them
Brodie
+1  A: 

There is no leak in the code that you have posted. When you tapped all 7 tabs then your app reaches 30MB of memory. But what happens if you continue to switch among tabs? Does it continue to increase in every switch? If yes, then you definitely have leak in some other portion. If not (i.e memory is more or less 30MB constant), then this might not be a problem at all. Sometimes system don't free up things until memory is required and 30MB is acceptable. It may also cache image data. You don't need to be worried in this case. Though I have found no Apple doc stating this feature, I have faced a similar scenario.

Apart from your original question, one thing is you should really avoid such big images (768x1024 pixel). This may cause huge problem, at least in low end devices.

taskinoor
thanks for your input - it is an iPad device so the 768x1024 is the smallest I can get. The reason I am asking is because didReceiveMemoryWarning is getting tripped and it's causing the views in my other tabs to reset. You are correct though, after the 7 tabs are opened, the memory usage stops going up.
Brodie
Another option that you can try is rather than depending on autorelease, alloc and release images on your own.
taskinoor
That did it - doing the releaseing myself worked like a charm - Thanks!
Brodie