0

I created a sample application that where I have a basic fullscreensize UIImageView set as the background. This app is very simple. All it is is 2 pages. (I will post the code below). The NIB only as UIImageView. I have tried 2 different scenarios -

Is there a problem with releasing NIB files and images.

I have been experiencing some memory leaks.

1) Example 1 (BAD)- I load the image directly in to the NIB. When I push the view, memory goes up by 5MB. When I pop (using NavigationController) the View off of the top, memory only goes down by a 1.5MB. Dealloc is indeed called. I have no IBOutlets. So, to me this is either caching or retaining this image in memory somewhere.

2) Example 2 (GOOD)- Set an IBOutlet for the UIImage view and I put the image in the UIImageview as shown below(I know I could create the UIImageView programmatically, but I am testing memory here not my screen creation skills). This cleans up nicely after itself. It removes the image from memory and I can see in Instruments that memory goes down.

@interface Page3VC : UIViewController {
    UIImageView*backimage;
}
@property(retain, nonatomic) IBOutlet UIImageView*backimage;
end

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];

    backimage.image = [self getImage:@"hipHome.png"];
}
-(void)viewDidDisappear:(BOOL)animated {
    backimage.image = nil;

    [super viewDidDisappear:animated];
}

-(UIImage*)getImage:(NSString*)imageName{
    //return [UIImage imageNamed:imageName];
    return [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:imageName ofType:nil]];
}
smcdrc
  • 1,671
  • 2
  • 21
  • 29

2 Answers2

3

Loading images via the NIB can be problematic -- it's known to 'leak' due to caching behaviour, but this is by design -- please see this question. This caching is useful for showing small images in UITables (high performance), but not good for loading a single huge image into your UI.

We need to see more of your code! How is getImage defined?

If you're using UIImage imageNamed: anywhere in your own code, you should be aware that it caches loaded images in memory. Dealloc'ing such an image won't actually unload the cached image in memory!

For more info, please see:

Difference between [UIImage imageNamed...] and [UIImage imageWithData...]?

Community
  • 1
  • 1
occulus
  • 16,959
  • 6
  • 53
  • 76
  • I added the getImage method above (not using ImageNamed). – smcdrc Mar 15 '11 at 18:01
  • @smcdrc No way to clear the image cache that I've ever heard of! – occulus Mar 16 '11 at 02:40
  • @smcdrc Thanks for adding the getImage method. I can see that you're using UIImage in a way that *doesn't* do behind the scenes caching, so this matches up with your problem description and confirms to me my original answer -- i.e. images loaded in a NIB are loaded via the imageNamed method which does caching behind the scenes, which is the crucial difference here. – occulus Mar 16 '11 at 02:42
  • @smcdrc Please see the top answer to this question: http://stackoverflow.com/questions/289360/problem-deallocing-memory-used-by-uiimageviews-with-fairly-large-image-in-an-uis It details a workaround that lets you still define things in a NIB (but defer loading the image until in your own code, where you can use a non-caching method to load the image). – occulus Mar 16 '11 at 02:45
  • Flagged my answer for checking out, looks like another vengeance down-vote. – occulus Mar 19 '11 at 18:30
0

in scenario 2 you should also release backimage before to set it to nil...

and please post the code where you load/init your UIViewController subclass...

and where you release it...

i mean, we see the objects loaded inside your class, but the problem could be outside it, when you load and use your class (application delegate? a rootMainUIViewController / navigation controller?)

meronix
  • 6,175
  • 1
  • 23
  • 36