• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: How far with accessors?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How far with accessors?


  • Subject: Re: How far with accessors?
  • From: Marcel Weiher <email@hidden>
  • Date: Fri, 28 May 2004 09:09:24 +0100

The -dealloc method *is* part of the implementation.

Sure. Just like -init, in which you seem to support the usage of
accessors.

I find them *convenient* in -init. And in -init, I am not destroying the object, so I am much more likely to want to have normal access to my instance variables.

Does not change the slightest bit the fact that the accessors
encapsulate the usage of whatever they give access to, and therefore
they should be used exclusively: nowhere but in them the actual storage
should be accessed directly (that is, in the normal average case, of
course that each rule has its exceptions).

If we had garbage collection, that might be true. However, we do not have garbage collection.

This is your personal opinion, not widely shared.

No.

Yes.

It is an opinion of much wiser (and, far as Cocoa is concerned,
more important) people than me,

I did not say "not shared at all". I said "not widely shared".

and it just happens to be shared by me.
By that, I am quitting this part of the debate: it is in archives for
anyone interested.

Good.

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.

Wrong.

Yes, what you say after this is wrong.

It may be that there is a notification to be sent when a
concrete property value is removed.

Good example: you typically do *not* want such notifications to be sent "by default" when you are destroying an object. For example, the object notified my want to access to originating object, which is the one you are currently destroying. Whoops!

Instead, you want a specific "I am not being destroyed" message, if anything at all. Think about garbage collection again: an object will usually go quietly, even if it has accessors defined.

It may be that there is an
independent storage of weak references, from which the old property is
to be deleted explicitly. There's a world of possible actions to be
taken when the old property value goes poof: you would have us to keep
the track of them explicitly and duplicate them both in the setter and
in -dealloc.

Wrong. You simply factor out the duplicated code and call it from both places. Duh. And once again, you don't want that to happen willy nilly by default.

If it is your preferred style, all right; myself though, I
prefer to write my code just once and share it. (*)

Duh.

-(void)setFoo:f { [foo autorelease]; foo=[f copy]; }

Copying in the accessor is *not* a general pattern, it is applicable
only to specific circumstances.

Nope. It is a *very* general pattern; for "has-a" properties (of which
I daresay in practice there's a majority) actually the main and
preferred one.

Nope. It is only useful when you are trying to emulate a language with "value" semantics in a pointer-based one, without any hope of ever actually succeeding, but likely deluding yourself that you have succeeded.

For a good reason, too: retaining (in other words, sharing) a mutable
property is a *very* dangerous practice, which tends to raise its ugly
head and bite your back at the first upgrade, when you in one module
change the shared value, forgetting meantime there's another module
which shares it, and which would rather keep the original one. (Of
course, with immutables, copying is exactly as cheap as retaining.)

QED.

-foo { return [dict objectForKey:@"foo"]; }
-(void)setFoo:f { if (f) [dict setObject:f forKey:@"foo"]; else [dict
removeObjectForKey:@"foo"]; }

Excellent example!

Thanks. Am flattered.

In this case, he will have a dictionary instance variable, which he
can just release with
[dict release];

Which does sweet nothing e.g., in case the dictionary happens to be
shared with another object, which stores different things there.

It does not do "nothing", it decreases the retain count. And I have to admit I don't typically use shared dictionaries to store my object's private instance variables. If I do, that will be a sufficiently special case that I would unset that var explicitly. But I wouldn't change my general coding style to adapt to this special case.

That is my whole problem with your approach: you are saying that the common case should be adapted, and made considerably more complex, error-prone, difficult-to-debug and expensive, in order to handle a few rare and special cases, which can be handled perfectly well by dealing with them explicitly when they pop up.

To me that sounds like Murphy's law used as design guidance: a $300 vacuum tube *should* blow to protect a 5 cent fuse.

Sure, it will work, but it isn't good design.

Even if this (or similar) scenario does not apply, still there's the
problem with having to duplicate the setter code, as explained in (*)
above.

No. [var release] is all that is needed. It is a single message send, just like [self setVar:nil].

Finally, sure, it *is* possible that the class design is such that the
dealloc just *has to be* part of the accessor encapsulation scope:
nobody says it's not. What I am pointing out though is that it is an
*exception*, whilst the normal case, the rule, is that accessors could
not (and should not) include dealloc into their encapsulation scope.

And that is where you are wrong. Think about it for just a second. Say you have an object with 10 scalar (non Objective-C object) instance variables. What would dealloc have to do?

Yes, precisely: nothing, except for calling super's dealloc to eventually release the memory. You don't have to set integer or float values to zero (what would that gain?). The only exception to this do-nothing approach comes from our use of refcounting. And there, we have to make sure we release our *instance variables*. If we had a GC, which we don't at present, even that would be unnecessary, the object would just disappear. In fact, in most modern (copying) GCs, it would disappear simply by not being considered for copying to live-space, without it actually being looked-at individually.

Destroying is not access.

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.


References: 
 >Fwd: How far with accessors? (From: Ondra Cada <email@hidden>)
 >Re: How far with accessors? (From: Jeff Biggus <email@hidden>)
 >Re: How far with accessors? (From: cricket <email@hidden>)
 >Re: How far with accessors? (From: Jeff Biggus <email@hidden>)
 >Re: How far with accessors? (From: Ondra Cada <email@hidden>)
 >Re: How far with accessors? (From: Marcel Weiher <email@hidden>)
 >Re: How far with accessors? (From: Ondra Cada <email@hidden>)

  • Prev by Date: Re: Flattening Mac resource files?
  • Next by Date: Re: Subclassing an object's creation method (NSBezierPath's +bezierPath)
  • Previous by thread: Re: How far with accessors?
  • Next by thread: Re: How far with accessors?
  • Index(es):
    • Date
    • Thread