Re: NSDictionary refactoring (was that really a bug at all)
Re: NSDictionary refactoring (was that really a bug at all)
- Subject: Re: NSDictionary refactoring (was that really a bug at all)
- From: Marcel Weiher <email@hidden>
- Date: Thu, 10 Jun 2004 22:53:14 +0100
[part 1, part 2 follows in a later post]
-(void)takeAString:(NSString*)s
{
[lut setObject:[NSCalendar date] forCopyOfKey:s];
}
Whew, that was HARD! I think I am going to have to take the rest of
the day off.
Sadly no refactoring used.
You missed it? Your claim was that now all the clients would have to
have [setObject:anObject forKey:[aKey copy]] in their code. What do
you do when you have duplication like that? You refactor it. In this
case into a new method: -setObject:forCopyOfKey:, implemented thusly:
-(void)setObject:anObject forCopyOfKey:aKey
{
[self setObject:anObject forKey:[[aKey copy] autorelease]];
}
Anyway, did that avoid the copy ?
It wasn't *supposed* to avoid the copy. Hello? It was supposed to
avoid the unavoidable cluttering of client code that you claimed was
inevitable. Of course, it took only a single method to avoid it.
Oh I see, it didn't. Is it now impossible to have a mutable string
accidentally as a dictionary key ?
No. Just like it isn't impossible to have other mutable objects as a
dictionary key, even with the copy.
No it isn't. Write setObject:forKey: (still there!) and again you have
the same problem. This reduces the problem, but doesn't eliminate it.
The same is true of always copying the key. It only reduces the
problem, it doesn't eliminate it. It cannot eliminate it. So in
either case (copying or non-copying of keys) you have to rely on
*convention* to assure that keys don't change. Is this part clear at
all?
What is KVC going to use ? ForCopyOfKey or just forKey ? Would you
want to upgrade that with takeValue:forCopiedKey: ?
This is a completely different subject, dealing with backwards
compatibility when the mis-design has already been out in the wild for
a long time. I have already suggested that it would probably be best
to introduce a superclass that implements the non-copying behaviour,
with NSDictionary possibly remaining as is (or maybe getting flag(s) or
other mechanisms).
However, I must stress again that the actual behavior of NSDictionary,
to me, is not so much a problem, it is a SYMPTOM for an idea that is
wrong-headed and leads to these sorts of problems.
[A somewhat better solution would be setObject:forRetainedKey: and
keep setObject:forKey: as is.]
-setObject:forRetainedKey: would be the method that doesn't retain,
because client code has already done so. That should probably be
internal.
Would you not now in 99% of all cases write forCopyOfKey in your code ?
Nope. Just like Smalltalks don't use copies of keys and somehow remain
stable. Odd, isn't it?
Well you probably wouldn't. I suspect most would.
Or they just keep using NSDictionary as is?
[snip more backwards-compatibility that wasn't ever an issue]
in your mutable, NSCopying-copy-is-not-isEqual:- class, whose
instances you want to use as a NSDictionary key and live dangerously ?
Sorry, you are completely missing the point. That class was an example.
Hmm...where does it make more sense to make a copy... ?
In Tor 1) 1 million (*) places in user code, where every time it is
forgotten you get a hard to trace bug, or Tor 2) in NSDictionary
where it will be done for us at no extra cost and less client bloat
or Tor 3) der Zonk. Hmmmmmmm... I'm gonna choose Tor 2.
Wow! So you are also a member of Ondra's single-password society? I
think it needs to be resolved where you have the mutability, not in
every dictionary just in case.
?? Single password society ??
You should have paid attention to that part of the thread. It is a
society of people who write buggy code which assumes that just because
NSDictionary copies keys, and keys only, they don't have to worry about
mutability of their data.
Ondra gave an example of user names and passwords stored in a
dictionary, with the UI being a NSTextView, with the data extracted
using the -string method, which, alas, returns a refernce to the
internal mutable text storage, and will thus change over time.
Ondra claimed that it was much better for NSDictionary to handle the
copy, because (similar to what you said) otherwise it would clutter the
client code. However, and I am not 100% sure this was clear, if you do
that, all your (nicely-copied) user names will point to the very same
mutable password string!
Is it clear why this is the case? NSDictionary will copy the key for
you, but it won't copy the value, and if you are using NSTextView, then
the values will be just as mutable as the keys. Sure, your keys are
"protected", but you still get the same result.
So it turns out that NSDictionary's key-copying behavior didn't really
help at all, you still have to think about mutability and handle it
yourself in your code, otherwise your code will be buggy. Furthermore,
not only did NSDictionary's key-copying not help, it actually *hurt*,
because of the false sense of security it gave.
And since you have to deal with it anyway, it will also be taken care
of for NSDictionary's keys.
Is that at all comprehensible?
Anyway as it seems this thread is about repetition: It doesn't cost me
anything extra. The just-in-case-code makes NSDictionary more fail
safe as I don't have to worry/think about the use of any NSMutable
instances with NSDictionary.
Ding-ding-ding-ding. The candidate has chosen Tor 2 and gets the Zonk,
because the Zonk wasn't where he thought it would be!! *g*
What a perfect demonstration of the dangers, just like Ondras example,
and exactly my point. You *do* have to worry/think about mutable
instances in your NSDictionary, just like you have to worry/think about
mutability in general, because otherwise the values you store in your
dictionary could just all point to the very same mutable string
instance. Whoops! However, just because keys are copied (and even
that doesn't really help) you thought that NSDictionary does this
thinking for you, were lulled into a false sense of security, and got
zapped.
Cheers,
Marcel
_______________________________________________
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.