Re: How far with accessors?
Re: How far with accessors?
- Subject: Re: How far with accessors?
- From: Marcel Weiher <email@hidden>
- Date: Thu, 27 May 2004 22:25:08 +0100
But as far as coding style goes, it seems much less clear what is
happening,
and could cause troubles down the line.
Quite the contrary. You must try to think (as far as possible) in terms
of the class abstract interface, *not* its internal implementation.
The -dealloc method *is* part of the implementation.
If the instance uses and/or "contains" a helper object, the exact way
it stores (the reference to) it and the exact way it handles it should
be encapsulated in accessors,
If you want to *access* it, yes. However, the -dealloc method does not
want ot *access* it, it wants to get rid of it as quickly and quietly
as possible.
and wherever you work with the object,
you should use this encapsulation, *without presuming how it actually
looks like*. Therefore, the code should generally look somewhat like
this:
This is your personal opinion, not widely shared. Simpler accessors
offer tangible, provable benefits, whereas this more complicate form
offers "benefits" that have never been demonstrated to exist, and are
at best dubious.
// accessors, the *only* place the actual storage is accessed:
-foo { return [[foo retain] autorelease]; }
-(void)setFoo:f { if (foo==f) return; [foo release]; foo=[f copy]; }
I would use accessor macros:
idAccessor( foo, setFoo )
// other usage
-init {
...
[self setFoo:@"whatever"]; // *not* foo=@"whatever"
...
}
Agreed.
-printFoo { // or any other method which uses foo
NSLog(@"%@",[self foo]); // *not* NSLog(@"%@",foo);
}
Agreed.
-(void)dealloc {
...
[self setFoo:nil]; // *not* [foo release]
...
}
Disagree:
-(void)dealloc
{
[foo release];
[super dealloc];
}
[self setTheString:nil] implies that theString exists and that its
*value* is being set to nil.
However, [theString release] is clearly releasing the *object*.
Wrong level of abstraction. [self setTheString:nil] in fact implies
that the instance's property named "foo" is being removed.
No. It implies that you are sending yourself the -setFoo: message with
a nil argument. This could have various consequences, many of which
may not be desirable in the context of deallocation.
The concrete
way of removing it is (quite properly) encapsulated in the accessor
code.
It also seems to requires assumptions made about the setter's internal
code,
which the act of releasing an object should be oblivious to.
Again, it's exactly the opposite: [foo release] is what makes unneeded
assumptions about the setter internal code.
Patently false.
If you just use the setter
to remove the property, dealloc would work properly whatever the
accessors do (presumed they are not buggy, of course ;)).
You are making the unwarranted assumption that the accessors are
nothing more than simple accessors, and that the object is in a
well-defined state, which it is *not*, because you are currently in the
process of destroying it.
On the other
hand, had you use just [foo release] instead of the proper [self
setFoo:nil], the simplest change in accessors may break your code.
No. It would have to be a change in the instance-variable layout.
For
example, you may decide to use the quicker (and less robust) accessor
pattern
-foo { return foo; }
-(void)setFoo:f { [foo autorelease]; foo=[f copy]; }
Copying in the accessor is *not* a general pattern, it is applicable
only to specific circumstances. It is also not "quicker". Copying
objects is potentially very, very expensive.
In the "your" way, you have to remember to change the your dealloc to
[foo autorelease].
No, he most certainly does not.
Or consider that later on you decide to move the
property into a dictionary (for whatever reason, say, for an easy
XMLization):
-foo { return [dict objectForKey:@"foo"]; }
-(void)setFoo:f { if (f) [dict setObject:f forKey:@"foo"]; else [dict
removeObjectForKey:@"foo"]; }
Excellent example!
In this case, he will have a dictionary instance variable, which he can
just release with
[dict release];
Instead of stupidly setting all the keys the objects to nil first and
then releasing the dict.
Releasing is *not* accessing.
In all such cases, a setter used in dealloc (and, generally, accessors
consistently used through your code) would continue working properly.
Direct references to the instance variable would break.
You are quite wrong, it would not. You just release your instance
variables, not the attributes you provide accessors for. Very simple,
robust and quick.
(One should be able to freely rework setter methods without thinking
about how
someone might be using them to deallocate objects.)
Very definitely so. That's the *exact* reason why you should use the
accessors anywhere, including in dealloc.
No, that is the *exact* reason why you should do no such thing.
Releasing is not accessing.
Marcel
--
Marcel Weiher Metaobject Software Technologies
email@hidden www.metaobject.com
Metaprogramming for the Graphic Arts. HOM, IDEAs, MetaAd etc.
1d480c25f397c4786386135f8e8938e4
_______________________________________________
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.