Re: Accessor methods and (auto)release <Memory trail>
Re: Accessor methods and (auto)release <Memory trail>
- Subject: Re: Accessor methods and (auto)release <Memory trail>
- From: Ondra Cada <email@hidden>
- Date: Wed, 31 Jul 2002 04:28:43 +0200
On Wednesday, July 31, 2002, at 01:39 , Raphakl Delcroix wrote:
There seems to be a strange competition in all the documents on how to
implement accessor methods.
- (void) setValue:(Something *)newValue {
[value autorelease];
value = [newValue retain]; // or copy, OK.
}
seems to be the most current.
Well, it's the most simple, most failproof, most robust, and thence -- at
least in my opinion -- most recommended.
However, I read that :
"autoreleasing an object is an expensive operation" etc...
(http://www.stepwise.com/Articles/Technical/MemoryManagement.html)
It is more expensive than plain release, but I would argue that situations
where it would bring noticeable difference are rare -- and next to
non-existing in a newbie's code.
Nevertheless, if you are really biased to premature optimization, well,
just use
-(void)setValue:(Something*)newValue {
[newValue retain];
[value release];
value=newValue;
}
But am I sure that the instance variable is not used elsewhere ?
Because in that case I have to autorelease !
I fear I don't understand this. The autorelease is needed since newValue
might be equal to value. Whether value is used elsewhere (which would be
generally true) or not has nothing to do with it.
Then, the author proposes this code :
Well, I don't want to start a war, but it looks to me like a madness.
Since...
- (void) setTheory: (Theory *)newTheory
{
Theory *oldTheory = nil;
...the author is so bound to optimizations, he should consider that here
the initialization brings no advantage at all, but of course, means an
unnecessary instruction.
if ( theory != newTheory ) // If they're the same, do
nothing
...again, this would help only in case the situation when
theory==newTheory is frequent enough (if it is, we save a few ticks of
incrementing/decrementing the retain count; if it is not, we lose a few
ticks of the test). In average code, I would dare to estimate that theory=
=newTheory so rarely that this would actually slow the application down!
{
oldTheory = theory; // Copy the reference
theory = [newTheory retain];// First retain the new object
[oldTheory release]; // Then release the old object
}
Without the swap variable it can be done by a simpler way (unless you copy,
that is).
return;
Well, this is an easy way how to earn some money if you happen to be paid
by a source line ;)))
}
But I understand less the use of a swap variable. This code would be
more simple :
- (void) setTheory:(Theory *)newTheory {
if (theory == newTheory) return;
I would not do that for the reasons above. If you have reasons to believe
that theory==newTheory would occur often though, it might bring some -- in
my estimate *utterly* unimportant and invisible -- speedup.
// [self willChange]; if necessary (I know nothing about that).
// but that's perhaps the reason of a so complicated manner ?
Forget it. This applies with the database API (Enterprise Object Framework)
only, and the API is, triple alas, dead in ObjC. That is a disaster, but
in this thread it is kinda off topic.
[theory release];
theory = [newtheory copy/retain];
}
Alas, not only simple, but also incorrect in the case theory==newTheory &&
[theory retainCount]==1. If so, the release would *dealloc* the object,
and thus the subsequent retain/copy sent to the same object would crash
(or, with a multithreaded app, do even worse things).
(Heck, in this week I am writing it here the third or fourth time. Sigh.)
So, what to do ?
In normal application, there's no harm in the simplest
[value autorelease]; value=[newValue retain/copy];
If you have *very* strong reasons to believe that you need some
optimization here (eg. since the setter happens to be called many many
many times indeed), you might go
[newValue retain]; [value release]; value=newValue;
With copy you need an extra variable -- IMHO, this is very slightly more
readable than the idea from Stepwise, though of course functionally
equivalent:
id o=[newValue copy]; [value release]; value=o;
Moreover, if, in your specific code, it is highly probable that
newValue==value very often, you might go
if (newValue==value) return; ... the above ...
---
Ondra Hada
OCSoftware: email@hidden
http://www.ocs.cz
private email@hidden
http://www.ocs.cz/oc
_______________________________________________
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.