views:

117

answers:

3

I have an About View which I push onto a NavigationController. The view has one UILabel which is connected to an IBOutlet. In viewDidLoad I populate the UILabel with the bundle version number (a string). Testing with instruments suggested that the line marked with a comment is leaking memory: -

viewDidLoad {
    [super viewDidLoad];

    self.title = @"About";
    // Line below is the suggested culprit ***
    NSString *versionLabel = [[NSString alloc] initWithFormat:@"Version %@", 
            [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey]];

    self.applicationVersion.text = versionLabel;
    [versionLabel release];
    versionLabel = nil;
}

I'm assuming it is suggesting the NSString and not anything else on the line ...

My questions is Why ?

A: 

You don't even need to create an instance of NSString in that case, simply use the following method that acts on the NSString class (not an instance):

NSString *versionLabel = [NSString stringWithFormat:@"Version %@", 
                                             [[[NSBundle mainBundle] infoDictionary] 
                                            objectForKey:(NSString*)kCFBundleVersionKey]];

If you use NSString this way, you do not have to release versionLabel because memory was never allocated.

zPesk
The same memory is allocated in this code as in the original code. The allocated NSString instance is just autoreleased for you.
Rob Napier
That is how I had this before looking into the leak actually.
ShogoDodo
+2  A: 

My suspicion is that you're leaking the applicationVersion UILabel. That will cause the string to leak as a by-product. The most common reason for this on iPhone is failure to follow the NIB memory management rules.

Rob Napier
According to Nib memory management rules I should be releasing the IBOutlet in setView (if the view is nil) as UIViewController implements its dealloc as setView.I am not observing this if I add NSLog messages in viewDidLoad, setView and Dealloc. What I observe is dealloc getting called and thats it. My only log messages I see from setView are when the Xib loads ?????
ShogoDodo
A: 

It may actually be the mainBundle or infoDictionary that is leaking - it is possible that the system is caching one or other of those and thus they are being created and then never released.

Try adding in to your applicationDidFinishLaunching the code:

[[NSBundle mainBundle] infoDictionary];

Without any other code and see if Leaks points to that line as the location of the leak. In that case, caching is the issue and you can ignore it.

Peter N Lewis
Thanks I'll try that. I'm only ever seeing the link one in every 5 or 6 times when I'm entering the AboutView under Instruments ...
ShogoDodo
Your comment got me on the right track thank you Peter
ShogoDodo