knowledge-database (beta)

Current group: comp.lang.objective-c

Release an Object in a collection

Release an Object in a collection  
Kinou
 Re: Release an Object in a collection  
Sherm Pendley
 Re: Release an Object in a collection  
Michael Ash
 Re: Release an Object in a collection  
David Stes
 Re: Release an Object in a collection  
Sherm Pendley
 Re: Release an Object in a collection  
Tilo_Prütz
 Re: Release an Object in a collection  
Kinou
 Re: Release an Object in a collection  
Tilo_Prütz
From:Kinou
Subject:Release an Object in a collection
Date:Wed, 22 Dec 2004 17:09:22 +0100
Hello,

I'm trying to make a Stack in Objective-C, and I've got a problem with
memory management.
When I add an object to my collection, it receives a retain message.
That's ok. But when I dealloc my collection (by sending a release
message), how can I send a release message to all the objects that were
in the collection ?

For example if I use a NSMutableArray like that :

Integer *trois=[[Integer alloc] initWithInt:3];

printf("retain count %d\n",[trois retainCount]);

NSMutableArray* arrayTest = [NSMutableArray new];
[arrayTest addObject:trois];
printf("retain count %d\n",[trois retainCount]);
[arrayTest release];
printf("retain count %d\n",[trois retainCount]);

I see :
retain count 1
retain count 2
retain count 1

And that's ok, but with my collection I see :
retain count 1
retain count 2
retain count 2

The count is always 2 after releasing my collection. Any idea ?

PS : I'm french, so sorry for my poor english ...

--
Regards,
Vincent JOUSSE
From:Sherm Pendley
Subject:Re: Release an Object in a collection
Date:Wed, 22 Dec 2004 12:56:02 -0500
Kinou wrote:

> I'm trying to make a Stack in Objective-C

Tilo has already given one good answer, but here's another possibility.

A stack is really just an array with push and pop methods, so have you
considered simply adding -pushObject: and -popObject methods to
NSMutableArray with a Category?

@implementation NSMutableArray (MyStackMethods)

- (void) pushObject: (id)theObject {
[self addObject:theObject];
}

- (id) popObject {
id theObject = [self lastObject];
[self removeLastObject];
return theObject;
}

@end

sherm--

--
Cocoa programming in Perl: http://camelbones.sourceforge.net
Hire me! My resume: http://www.dot-app.org
From:Michael Ash
Subject:Re: Release an Object in a collection
Date:Wed, 22 Dec 2004 12:20:25 -0600
Sherm Pendley wrote:
> Kinou wrote:
>
>> I'm trying to make a Stack in Objective-C
>
> Tilo has already given one good answer, but here's another possibility.
>
> A stack is really just an array with push and pop methods, so have you
> considered simply adding -pushObject: and -popObject methods to
> NSMutableArray with a Category?
>
> @implementation NSMutableArray (MyStackMethods)
>
> - (void) pushObject: (id)theObject {
> [self addObject:theObject];
> }
>
> - (id) popObject {
> id theObject = [self lastObject];
> [self removeLastObject];
> return theObject;
> }
>
> @end

Better write popObject like this:

- popObject {
id theObject = [[[self lastObject] retain] autorelease];
[self removeLastObject];
return theObject;
}

If you don't do the retain/autorelease pair, then the object will be
destroyed if it's not retained elsewhere, and you'll probably tear your
hair out trying to find the problem.
From:David Stes
Subject:Re: Release an Object in a collection
Date:Wed, 22 Dec 2004 21:06:41 GMT
Michael Ash wrote:
> Better write popObject like this:
>
> - popObject {
> id theObject = [[[self lastObject] retain] autorelease];
> [self removeLastObject];
> return theObject;
> }

This is wrong; the -retain should be done by the method that uses -popObject.

[[someStack popObject] retain];

With your implementation, you will leak memory.

>
> If you don't do the retain/autorelease pair, then the object will be
> destroyed if it's not retained elsewhere, and you'll probably tear your
> hair out trying to find the problem.

Yes, but the alternative, of leaking memory, although slightly better
(no immediate crash) will eventually also result in a crash (due to leak)
From:Sherm Pendley
Subject:Re: Release an Object in a collection
Date:Wed, 22 Dec 2004 17:05:05 -0500
David Stes wrote:

> Michael Ash wrote:
>
>>Better write popObject like this:
>>
>>- popObject {
>> id theObject = [[[self lastObject] retain] autorelease];
>> [self removeLastObject];
>> return theObject;
>>}
>
>
> This is wrong; the -retain should be done by the method that uses -popObject.
>
> [[someStack popObject] retain];
>
> With your implementation, you will leak memory.

Utter nonsense - as is normal for David Stes. Neither my broken original
nor Michael's correction leaks.

Michael is right, retain/autorelease should be done within -popObject,
I'd overlooked that.

The problem with my original code - which David's "correction" does not
fix, but Michael's does - goes as follows:

id theObject = [self lastObject]; // theObject points to
// the last object. (duh)

[self removeLastObject]; // The last object is removed
// *and* *released*
// theObject now points to an
// object that has been released

return theObject; // An invalid object reference is
// returned - it's too late to
// fix the problem by retaining
// it in the caller.

Michael's fix causes the object to go into the autorelease pool, so when
it's removed from the array there's still at least one reference to it,
so it won't be immediately dealloced. It might still be dealloced later,
but the pool gives the caller a chance to retain the object before then
if it wants.

sherm--

--
Cocoa programming in Perl: http://camelbones.sourceforge.net
Hire me! My resume: http://www.dot-app.org
From:Tilo_Prütz
Subject:Re: Release an Object in a collection
Date:Wed, 22 Dec 2004 17:27:52 +0100
Kinou wrote:

> Hello,
>
> I'm trying to make a Stack in Objective-C, and I've got a problem with
> memory management.
> When I add an object to my collection, it receives a retain message.
> That's ok. But when I dealloc my collection (by sending a release
> message), how can I send a release message to all the objects that were
> in the collection ?
>


Have I understood you correctly? You implemented your own collection,
right? So you are sending retain to newly added objects, right?

Then on dealloc you have to iterate over all objects in your
collection and send them a(n) (auto)release.


greetz

>tilo
From:Kinou
Subject:Re: Release an Object in a collection
Date:Wed, 22 Dec 2004 17:41:30 +0100
Tilo Prütz wrote:
>
>
> Have I understood you correctly? You implemented your own collection,
> right? So you are sending retain to newly added objects, right?
>

Yes that's right.

> Then on dealloc you have to iterate over all objects in your
> collection and send them a(n) (auto)release.
>

So I have to implement my own dealloc method, iterating over all the
objects ? It seems to be obvious in fact ...

>
> greetz
>

Thanks !

--
Regards,
Vincent JOUSSE
From:Tilo_Prütz
Subject:Re: Release an Object in a collection
Date:Wed, 22 Dec 2004 20:04:11 +0100
Kinou wrote:
>
> So I have to implement my own dealloc method, iterating over all the
> objects ? It seems to be obvious in fact ...
>

Of course. You retained them so you have to release them.


greetz

>tilo
   

Copyright © 2006 knowledge-database   -   All rights reserved