Re: Accessor methods and (auto)release: conclusion
Re: Accessor methods and (auto)release: conclusion
- Subject: Re: Accessor methods and (auto)release: conclusion
- From: Marcel Weiher <email@hidden>
- Date: Tue, 6 Aug 2002 10:27:26 +0200
On Monday, August 5, 2002, at 11:15 Uhr, Ondra Cada wrote:
For diverse situations, diverse kind of accessors might be needed. For
a vast majority of cases though the following patterns should help:
A: normal, not thread-safe code
===============================
(A.i) simple objects, where the efficiency of a getter is very
important
-getter {
return ivar;
}
-(void)setter:newObject {
[ivar autorelease];
ivar=[newObject copy]; // or retain, depending on object & usage
}
1. Simple objects should not use -autorelease in the setter
2. A set-accessor should, per default, -retain the new object, *never*
copy it.
If it copies the object, the method is simply not an accessor any
longer and should be named differently to reveal to clients that it
will copy argument objects. Furthermore, note that if a setter copies,
a client cannot get sharing-behavior if they want to, whereas a client
can always disable sharing by doing a copy themselves with a simple
accessor.
You should also use [ivar autorelease] (instead of release) in your
-dealloc method, for the same reason you are autoreleasing in the
setter: so that the vended object would survive setting another or
releasing the vendor. You might consider using [self setter:nil] in
-dealloc instead of explicit (auto)releasing, for it would release the
ivar the proper way "automatically", depending on the setter you
actually use.
No. If you are making a 'container' go away while still using one of
its subparts, then that is simply a bug that should be fixed, and using
-autorelease just masks the bug. If I -dealloc an object, I should be
able to expect that its subparts will also go away immediately and not
stick around gratuitously.
If the class is meant to be *really* straighforward (say, a very plain
NSArray-like container), you might -- for simplicity's sake -- want to
use [ivar release] in -dealloc and the A.ii setter (shown below); do
mention explicitly in documentation though that programmers should
retain what they got!
No, this should be the other way around.
(A.ii) normal objects (presumably a majority of classes)
-getter {
return [[object retain] autorelease];
}
Same issue as above: a simple accessor has no business autoreleasing.
-(void)setter:newObject {
if (ivar==newObject) return;
[ivar release];
ivar=[newObject copy]; // or retain, depending on object & usage
}
This should be the default set-accessor (apart from the copy-issue).
[I have no issues with the threaded case]; -)
General note: these patterns are meant to be used in newly written
code. The current Cocoa frameworks for diverse -- mainly historical
and compatibility -- reasons often does not use them the most correct
way, even without a proper documentation; this will eventually change.
Once again, I disagree that these patterns should be used in new code.
They may appear convenient at first, but they just try to hide the fact
that Objective-C (with retain/release) is *not* a garbage collected
language. The problem is that the way they hide it makes code both
much less transparent and slower performing.
Simplicity and transparency are important, because they allow
developers to form a mental model of what actually happens in the code.
These patterns just obscure. Simplicity has always been one of
Objective-C's great strengths, and this just adds layers of complexity.
Marcel
--
Marcel Weiher Metaobject Software Technologies
email@hidden www.metaobject.com
Metaprogramming for the Graphic Arts. HOM, IDEAs, MetaAd etc.
_______________________________________________
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.