0

I'm using the profiler in xcode 4 to determinate if I have any memory leaks. I didn't have this leak before, but with xcode 5 I have this one.

I'm trying to set an image for the tab item of my `UIViewController and the profiler marks this line :

    image = [[UIImage alloc] initWithContentsOfFile:imgPath];   <<=== Leak : 9.1%

This is part of my code I don't understand why. What's the best way to resolve this issue?

    NSString *imgPath;
    UIImage *image;

    IBNewsViewController *newsView = [[IBNewsViewController alloc] initWithURL:[tvLocal urlFlux] title:@"News" isEmission:NO];
    [newsView setTitle:@"News"];
    imgPath = [[NSBundle mainBundle] pathForResource:"news" ofType:@"png"];
    image = [[UIImage alloc] initWithContentsOfFile:imgPath];   <<=== Leak : 9.1%
    newsView.tabBarItem.image = image;
    [image release];
    image = nil;
    UINavigationController* navNew = [[UINavigationController alloc] initWithRootViewController:newsView];
    [newsView release];
    newsView = nil;

EDIT: No leak on iOS6.

Why it's leak on iOS7?

JND
  • 170
  • 2
  • 12

3 Answers3

0

Replace this line

image = [[UIImage alloc] initWithContentsOfFile:imgPath]; 

With

image = [UIImage imageWithContentsOfFile:imgPath];

and check once.

Popeye
  • 11,839
  • 9
  • 58
  • 91
Ganapathy
  • 4,594
  • 5
  • 23
  • 41
0

You should switch to the autoreleasing imageNamed: method. This has the added benefit of system level cacheing of the image.

NSString *imgPath;
UIImage *image;

IBNewsViewController *newsView = [[IBNewsViewController alloc] initWithURL:[tvLocal urlFlux] title:@"News" isEmission:NO];
[newsView setTitle:@"News"];

image = [UIImage imageNamed: @"news"];   
newsView.tabBarItem.image = image;

UINavigationController* navNew = [[UINavigationController alloc] initWithRootViewController:newsView];
[newsView release];
newsView = nil;

To make life easier on yourself I'd switch your project to use ARC so you have less to worry about WRT memory management.

Ashley Mills
  • 50,474
  • 16
  • 129
  • 160
  • i am using Arc and i get some leaks for [imageview setImage:[UIImage imageNamed:@"img-568h@2x"]]; only in simulator for now – dave Oct 16 '13 at 10:52
0

First, switch to ARC. There is no single thing you can do on iOS that will more improve your code and remove whole classes of memory problems with a single move.

Beyond that, the code above does not appear to have a leak itself. That suggests that the actual mistake is elsewhere. There are several ways this could happen:

  • You're leaking the IBNewsViewController somewhere else
  • IBNewsViewController messes with its tabBarItem incorrectly and leaks that
  • You're leaking the UINavigationController somewhere else
  • You're retaining the tabBarItem.image somewhere else and failing to release it

Those are the most likely that I would hunt for. If you're directly accessing ivars, that can often cause these kinds of mistakes. You should use accessors everywhere except in init and dealloc. (This is true in ARC, but is absolutely critical without ARC.)

Leak detection is not perfect. There are all kinds of "abandoned" memory that may not appear to be a leak. I often recommend using Heapshot (now "Generation") analysis to see what other objects may be abandoned; that may give you a better insight into this leak.

Why differences in iOS 6 vs iOS 7? I suspect you have the same problem on iOS 6, but it doesn't look like a "leak", possibly because there is something caching the image that was removed in iOS 7. The cache pointer may make it look like it's not a leak to Instruments.

Speaking of which, do make sure to run the static analyzer. It can help you find problems.

And of course, switch to ARC.

Community
  • 1
  • 1
Rob Napier
  • 286,113
  • 34
  • 456
  • 610