Question

I have a simple method in my model to create a NSDictionary object containing its properties. Unfortunately this method is seen by "Analyse" to be leaking memory :

Potential memory leak of an object allocated on line 76 (marked here with a dot) and stored in 'dic'.

-(NSDictionary*) getDictionary {
    NSDictionary *dic = [[NSDictionary alloc] init];

    [dic setValue:(id)self.internal_code forKey:@"internal_code"];
    [dic setValue:(id)self.identifier forKey:@"id"];
    [dic setValue:(id)self.owner forKey:@"owner"];
    [dic setValue:(id)self.address forKey:@"address"];
    [dic setValue:(id)self.displayed_name forKey:@"displayed_name"];

    return dic;
}

I am not using ARC.

PS : To people coming in, the original code I posted was correct — it had an autorelease. I edited it after so the memory leak would reappear and to ask precisely why.

Was it helpful?

Solution

When returning an object from a method that doesn't begin with alloc, copy, mutableCopy or new, that object must be returned as autoreleased.

More conceptually, it should not be owned by your code when you return it. You take ownership of an object when you type alloc, copy, mutableCopy or new. You relinquish ownership when you type release or autorelease.

You can either change your return statement to:

return [dic autorelease];

Or better is to keep the alloc/init/autorelease all on one line so the code is easier to review, and the alloc and release cannot become separated by accident while copy and pasting code:

NSDictionary *dic = [[[NSDictionary alloc] init] autorelease];

An even easier way is to use this convenience constructor on NSDictionary:

NSDictionary *dic = [NSDictionary dictionary];

The above lines will fix the memory leak. However, you are also trying to mutate an immutable type (NSDictionary). You should be using a mutable dictionary instead:

NSMutableDictionary *dic = [NSMutableDictionary dictionary];

Finally, you should ideally be setting values with the setObject:forKey: method, although setValue:forKey: will also work.

For more information on memory management, read the Advanced Memory Management Programming Guide.

If you are targetting iOS 4 or later, I would highly recommend using ARC.

OTHER TIPS

Try to autorelease while returning the dic as below

return[dic autorelease];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top