views:

398

answers:

3

So some where i have a leak which is related to deleting an object under certain circumstances.

Premise: - I have an NSMutableArray of Tree objects (a Tree object knows how to draw itself). - I have a reference pointer (Tree *selected) which basically points to whatever tree i last touched. - Note that the *selected pointer is a weak reference.

Ok, so far so good.

Problem: The leak arises when i delete a Tree. From the list i make sure the tree being deleted is releasing everything internally before removing it from the array (removing it from the array should automatically call release on it).

What i tried: I noticed that my Tree *selected pointer is being assigned the touched tree via the self property:

self.selected = tree;

...and by doing this i know that it is being retained. So what i tried to do was call:

[self.selected release];

I called this right after the tree is removed from the array. ...but at which point it crashes essentially stating it was already released.

Question: Why am i getting this error message? I removed it from the array, however my self.selected pointer still has a retained count, thus shouldn't i be releasing it?

Perhaps I should set it to nil after the removal process? Or, perhaps I should set it to autorelease BEFORE the removal process?

A: 

What's [probably] happening is selected points to a deallocated object, not nothing.

I'd try

self.selected = nil;

instead of releasing it explicitly. That should take care of the retain count, too.

Wevah
+1  A: 

Don't attempt to micromanage the retaining/releasing of your selected instance variable. If you want selected to be a weak reference, declare it with the assign attribute:

@property(nonatomic, assign) Tree *selected;

That way it will not be retained when you assign a value to it. Conceptually, it will "piggyback" on the reference that your NSMutableArray is keeping. So when you remove something from your NSMutableArray, do it a bit like this:

if (self.selected == toBeRemoved)
    self.selected = nil;
[myArray removeObject:toBeRemoved];

If you didn't explicitly specify assign and your property was retaining its contents, you were most likely getting an exception because the next assignment to self.selected after removing an element caused another -release message to be sent to the old value, which had already been released by your [self.selected release] message.

John Calsbeek
A: 

basically, i was assigning my weak references using 'self', thus internally calling retain. i removed the 'self' and now things are fine and dandy. :) thanks!

Edward An