Re: How far with accessors?
Re: How far with accessors?
- Subject: Re: How far with accessors?
- From: Ondra Cada <email@hidden>
- Date: Thu, 27 May 2004 13:02:29 +0200
Jeff,
On 27.5.2004, at 1:36, Jeff Biggus wrote:
>
> [self setTheString:nil] will release the object and nil out the
>
> instance variable in one swell foop. That's why it's a nice way to do
>
> it.
>
>
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.
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, 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:
// 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]; }
// other usage
-init {
...
[self setFoo:@"whatever"]; // *not* foo=@"whatever"
...
}
-printFoo { // or any other method which uses foo
NSLog(@"%@",[self foo]); // *not* NSLog(@"%@",foo);
}
-(void)dealloc {
...
[self setFoo:nil]; // *not* [foo release]
...
}
>
[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. 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. 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 ;)). 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. 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]; }
In the "your" way, you have to remember to change the your dealloc to
[foo autorelease]. 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"]; }
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.
>
(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.
(Of course, all rules have its exceptions, and there are good cases
sometimes to access ivars directly; but, like it is with all
optimizations, it should be done *ONLY* if there are strong reasons to,
*never* otherwise.)
---
Ondra Hada
OCSoftware: email@hidden
http://www.ocs.cz
private email@hidden
http://www.ocs.cz/oc
[demime 0.98b removed an attachment of type application/pkcs7-signature which had a name of smime.p7s]
_______________________________________________
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.