views:

58

answers:

5

I have a class like this:

@interface MyCollection : NSObject {
    NSMutableDictionary *data;
}

and in the implementation of it, I have a method to init it like this:

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

Now when I create a object of this class in my code like this:

MyCollection *c = [[MyCollection alloc] init];

... at which point the Leaks utility shows that I have a memory leak in the init function on the very line where I try to set up the instance variable. I am totally new to Objective C & Iphone and I can't just get what is going wrong here. I have read through the Memory Management Guide and all, but I think I'm missing something pretty serious here.

Any help would be greatly appreciated. Thanks for your time already.

+1  A: 

You have to release the object in your dealloc method. That's why it's showing up as a leak.

Jasconius
I do release the object like so: - (void) dealloc { [data release]; data = nil; [super dealloc];}
kumar
@kumar: No need to set `data` to `nil` inside `dealloc`. `dealloc` is the last method to be invoked before the object is actually removed from memory, so setting it to `nil` is an unnecessary/redundant step.
dreamlax
Noted. I wish removing the nil assignment would work, but it doesn't. :(
kumar
+4  A: 

you are using self.data =. So there is most likely a property. And it most likely is a property which either copies or retains your object if you use it.
By calling

 self.data = [[NSMutableDictionary alloc] init];

The retain count of the NSMutableDictionary increases because of the alloc, and if the property of data has a retain or copy statement you get another increase in retain count.

you could write data = [[NSMutableDictionary alloc] init]; or self.data = [NSMutableDictionary dictionary]. This would increase the retain count only one time.

And don't forget to release the object in dealloc.

fluchtpunkt
I have already tried all of what you have suggested, but still it persists. And I release the object as well in the dealloc method of the class, but no help.
kumar
A: 

Are you creating the instance of "MyCollection" in the interface section?

If it has method scope try to release it in the same method after you are done with it.

Sepehr
No, I am using this class in my application code and there is where its leaking.
kumar
+1  A: 

to add to what fluchtpunkt mentioned you could try this instead:

- (id) init {
    if(self = [super init])
    {
        self.data = [NSMutableDictionary dictionaryWithCapacity:0];
    }
    return self;
}

and in the dealloc

-(void)dealloc
{
  self.data = nil;
}
Anders K.
The dictionaryWithCapacity was an important addition for this case. And going by what fluchtpunkt said, I'm using data instead of self.data
kumar
A: 

I see weird situations with the Leaks utility as sometimes it reports old leaks, sometimes it doesn't report new ones, and so on. Also, from what I could collect with all your answers and opinion elsewhere on the web, people are divided on whether one should set a pointer to nil or not. As of now, I have solved the situation with the following approach.

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

-(void)dealloc
{
    [data release];
}

Thanks everyone for contributing.

kumar