Re: simple array release error question
Re: simple array release error question
- Subject: Re: simple array release error question
- From: Marcel Weiher <email@hidden>
- Date: Sun, 1 Jun 2003 12:30:40 +0200
Doing the following is perfectly ok but only if you had alloc-ed,
copied, or retained the items you put in the array. (also it is better
ask the array how many items it has)
for(i = 9; i >= 0; i--)
[[array objectAtIndex:i] release];
Technically you are correct, this could be OK. "Stylistically" I would
say this is never OK, and the reason for that is actually (sort of) in
your description:
In your code snippet you did not list how the things you are putting
into the array got created. They are most likely being created for you
by something else and hence you are getting an object that is already
in the autorelease pool. So you are not responsible for getting them
deallocated.
The fact that you don't see anything that allows this in the code
snippet is a strong tip-off that you shouldn't be doing this.
If it were alloced/copied or retained, there must (should) have been an
object reference (pointer) that was alloced/copied or retained before
it got put in the array. It should be this reference that gets the
release, and it should get it preferably as soon as it is put in the
array.
So:
for (i=0; i<9;i++ ) {
id newRef=[[MyObject alloc] init];
[array addObject:newRef];
[newRef release];
}
The point is that the release is easily traceable to the alloc+init.
Since this is sort of a pain, I usually use autorelease in this case:
for (i=0;i<9;i++ ) {
[array addObject:[[[MyObject alloc] init] autorelease]];
}
Although what I probably should do is add the following method to
NSMutableArray:
-(void)addAndReleaseObject:anObject
{
[self addObject:anObject];
[anObject release];
}
Then I could just write:
for (i=0;i<9;i++ ) {
[array addAndReleaseObject:[[MyObject alloc] init]];
}
The somewhat interesting part of this is that the retain implied by
-addObject: and the release cancel each other out, so an optimized
implementation could reverse these two methods and implement
addAndReleaseObject: without modifying the retainCount at all:
-(void)addAndReleaseObject:anObject
{
//--- only for illustration purposes, not complete or correct!
myStorage[count++]=anObject;
}
-(void)addObject:anObject
{
[anObject retain];
[self addAndReleaseObject:anObject];
}
This may seem just a small optimization, but it can have a rather large
impact for objects that subclass NSObject and do not implement their
own inline-reference count. For these objects, the first (implied)
retain is 'free', but going over that causes an external reference
count to be allocated + accessed via hash. Furthermore (not 100% sure
about this), the immediate decrement of the reference count then causes
the external reference count to be deallocated again. This gives you 2
extra trips to the malloc library, and that is roughly an order of
magnitude more expensive than message sending or an inline retain-count.
--
Marcel Weiher Metaobject Software Technologies
email@hidden www.metaobject.com
Metaprogramming for the Graphic Arts. HOM, IDEAs, MetaAd etc.
f0249ab8b1af193ef5addcf39fdff5ca
_______________________________________________
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.