Re: NSMutableDictionary not sending release message to contained objects at dealloc time
Re: NSMutableDictionary not sending release message to contained objects at dealloc time
- Subject: Re: NSMutableDictionary not sending release message to contained objects at dealloc time
- From: Greg Hurrell <email@hidden>
- Date: Sun, 13 Apr 2003 07:48:42 +0930
Argh!
I cannot believe the number of people who have tried to tell me I don't
understand how autorelease works. These people simply haven't been
reading my code or my comments. Autorelease is one thing that I
actually do understand! The fact that in my code sample I have been
using an autoreleased dictionary and autoreleased array is just a
coincidence. I could've written the same snippet using manually
allocate and released items.
The line that was given me trouble is the one where I do a
"removeObjectAtIndex" and the retain count on the removed object did
not go down, which to me seemed both counterintuitive and to run
against what was implied in the Cococ docs.
Bearing that in mind:
For reference, the original code:
MYObject *obj = [[MYObject alloc] init];
NSMutableDictionary *dict = [NSMutableDictionary
dictionaryWithObjectsAndKeys:obj, @"Key", nil];
NSMutableArray *arr = [[NSMutableArray arrayWithObjects:dict, nil];
NSLog(@"Retain count on obj is %d", [obj retainCount]); // count is
2
(correct)
// remove the dictionary, which should send release to obj as well
[arr removeObjectAtIndex:0];
NSLog(@"Retain count on obj is %d", [obj retainCount]); // count is
still 2 (INCORRECT!)
Greg wrote:
It shouldn't. The contents of the dictionary should be sent a release
message when the dictionary itself is releaed, to balance the retain
message they are sent when added to the dictionary.
But that's not what your code does. The dictionary is not released
until LATER! You are, as I suspected, misunderstanding what
autorelease does.
You are correct, the dictionary is not DEALLOCATED until later (ie.
when it is autoreleased). It should, however, receive a release message
at the time that it is removed from the array, to balance the retain it
received when added to the array.
So it is not me who fails to understand autorelease, because the
autorelease in the above snippet is incidental and has nothing to do
with the line in question. At this point I could make a comment about
you, as I suspected, misunderstanding how items are retained/released
when added to/removed from a mutable collection class; but I won't say
this because evidently you DO understand it. It's just that you have
misread my concern, and have been distracted in this thread by the
bunch of people lecturing me on autorelease (which I didn't need) when
what I was really asking about was the behaviour of collection classes.
You've got that right. You are misunderstanding WHEN autorelease does
its job
Again, see above. I understand autorelease. Autorelease has nothing to
do with my original question.
, which is not until (at least) execution leaves the scope where dict
was declared. The Application Kit creates a an autorelease pool at
the beginning of the event loop. Objects (like dict) are added to
this pool, and the pool is released at the end of the event loop. The
execution of the code you posted all happens within the same event
loop, so the same pool sticks around and, as a result, dict sticks
around.
READ the code, for god's sake. In particular:
NSLog(@"Retain count on obj is %d", [obj retainCount]); // count
is 2
(correct)
// remove the dictionary, which should send release to obj as well
[arr removeObjectAtIndex:0];
NSLog(@"Retain count on obj is %d", [obj retainCount]); // count is
still 2 (INCORRECT!)
Of course no autorelease occurs here. Do YOU understand autorelease? If
I expected the dictionary to be autoreleased, sending it a
"retainCount" message would crash the code because I'd be sending a
message to a deallocated object.
It's not me who needs to learn about autorelease; it's just about
everybody else that needs to learn that when someone says "release",
he/she is only saying, "Object has a 'release' message to it, which
will reduce its retainCount by one". Clearly a release message does NOT
always result in the deallocation of an object, but always in the
reduction of its retain count by one.
This is exactly what you probably would want in a real program.
I know, which is why when I saw that it wasn't happening I sent a
message to the list.
Your code may need to do something with dict after it is removed from
the array, e.g., pass it as an argument to another method.
Indeed the code in question does quite a few things with said
dictionary. I peppered my code with NSLog statements which showed the
retain count on the dictionary at various points, and at one point the
retain count didn't go down by one when it was removed from an
NSMutableArray. Just for the sake of clarity, I did not expect the
dictionary to be totally deallocated at this point, but I did
(reasonably) expect the dictionary's retain count to go down by one.
Thanks to Phill's excellent demonstration code, he proved the way
things should behave at the time an object is removed from a collection
class. But I still have no idea why I am seeing the retainCount problem
at one specific point in my code. But given that I now have proof of
how Cocoa should be behaving, I'm not going to worry about it. It can
be a problem for another day.
Greg
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.