开发者

Compiler says there is a memory leak, but I don't see one

开发者 https://www.devze.com 2023-04-06 02:18 出处:网络
So I did that thing with Xcode where you say analyze and it finds leaks and stuff and here, it says that I am leaking (marked in code below).

So I did that thing with Xcode where you say analyze and it finds leaks and stuff and here, it says that I am leaking (marked in code below).

// Copy dictionary to memory
NSString *filepath = [[NSBundle mainBundle] pathForResource:@"Da开发者_开发技巧taCategoriesDictionary" ofType:@"plist"];
NSDictionary *dataCategoriesDictionary = [[NSDictionary alloc] initWithContentsOfFile:filepath];
self.choices = [[NSMutableDictionary alloc] initWithDictionary:[dataCategoriesDictionary objectForKey:self.chosenCategory]]; // LINE 55
[dataCategoriesDictionary release]; // HERE, the compiler says "Potential leak of an object allocated on line 55"

Even though it doesn't make any sense that I could be leaking a instance variable, I tried adding a release statement for it anyway and Xcode still gave me the same error. What else could I be leaking?


If choices is a property with retain you are leaking the NSMutableDictionary.

[[NSMutableDictionary alloc] initWithDictionary

Either autorelease or use a temporary.

self.choices = [[[NSMutableDictionary alloc] initWithDictionary:[dataCategoriesDictionary objectForKey:self.chosenCategory]] autorelease];

or (my favorite)

self.choices = [NSMutableDictionary dictionaryWithDictionary:[dataCategoriesDictionary objectForKey:self.chosenCategory];

or

NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] initWithDictionary:[dataCategoriesDictionary objectForKey:self.chosenCategory]];
self.choices = tempDict;
[tempDict release];


choices looks like a Declared Property. It seems that you'd declared it like below:

In .h file:
@property (nonatomic, retain) NSMutableDictionary *choices;

In .m file:
@synthesize choices

In this case, the compiler automatically provides the setter method:

-(void) setChoices:(NSMutableDictionary*)newValue
{
    if (choices != newValue) {
        [choices release];
        choices = [newValue retain];
    }
}

From your code, self.choices implicitly calls setChoices method. So newly allocated NSMutableDictionary's retain count become 2 not 1, result in object leak.


You should be releasing the member variable (ivar) that the property choice refers to. So assuming there is a member variable _choice then releasing it like this:

[_choice release]

should work.

Alternatively, if you rewrote it like this it might make it clearer why there is a leak:

NSMutableDictionary * temp = [[NSMutableDictionary alloc] initWithDictionary:[dataCategoriesDictionary 
self.choices = temp
[temp release]
0

精彩评论

暂无评论...
验证码 换一张
取 消