views:

242

answers:

1

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?

+2  A: 

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.
Tom Irving
I would add that you should never use the method form of reference in dealloc.So, never use self.propertyName of [self getPropertyName] to release. Doing so calls the methods which can have unpredictable results if your accessors are more complicated.
TechZen
Or just use `[self setMyDict: [NSMutableDictionary dictionary]]`
St3fan
Inspired by your real good comments, I read a lot more on property declarations and found the dynamic declaration of ivars by the 64-Bit Runtime. Unfortunately they are not usable with iPhone-Simulator. But if one want to reduce later re-work, when the feature is available for Simulator one should use the following:in init: [self setMyDict: [NSMutableDictionary dictionary]]in dealloc: [self setMyDict:nil]
maxbareis