Question

With the following code the analyzer marks the setMyDict selector call as a potential leak and in dealloc it states "Incorrect decrement of the reference count is not owned at this point by the caller"

- (id)init {
  if (self = [super init]) {
      [self setMyDict:[[NSMutableDictionary alloc] init]];
  }
  return self;
}

- (void)dealloc {
  [[self myDict] release];
  [super dealloc];
}

@synthesize myDict = _myDict;

I do not understand this. I thought, that with the alloc init the object increases the retain count by one and the pointer is stored in _myDict through the synthesized property. If I use this code instead

- (id)init {
  if (self = [super init]) {
    _myDict = [[NSMutableDictionary alloc] init];
  }
  return self;
}

- (void)dealloc {
  [_myDict release];
  [super dealloc];
}

Analyzer does not complain. What am I missing?

Was it helpful?

Solution

The @synthesize provides you with a setter and getter for the object you're synthesizing.

A setter method looks something like this (taken from the Apple docs)

-(void)setMyDict:(NSMutableDictionary *)newDict {
    if (myDict != newDict) {
       [myDict release];
       myDict = [newDict retain];
    }
}

You're creating a leak when you do:

[self setMyDict:[[NSMutableDictionary alloc] init]];

Because you never release the newly alloc'd dictionary.

A way to work around this is:

NSMutableDictionary * dict = [[NSMutableDictionary alloc] init];
[self setMyDict:dict];
[dict release];

This takes care of the leak.

In the dealloc method, you should use:

[myDict release]; // Or whatever your property is called.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top