Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!)
Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!)
- Subject: Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!)
- From: Nat! <email@hidden>
- Date: Tue, 15 Jun 2004 01:21:38 +0200
[This mail got stuck last week, probably due to size. Here's a trimmed
down version.]
Am 09.06.2004 um 02:50 schrieb Nat!:
Am 08.06.2004 um 14:32 schrieb Marcel Weiher:
[
Ok so put yourself to the challenge and figure out with subclasses,
categories and especially that power tool refactoring, how to make
sure that you don't end up with an NSMutableString as the key in a
dictionary in my method "takeAString".
-(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. Anyway, did that avoid the copy ? Oh I see,
it didn't. Is it now impossible to have a mutable string accidentally
as a dictionary key ? No it isn't. Write setObject:forKey: and again
you have the same problem. It reduces the frequency of the problem, but
it doesn't eliminate it.
What is KVC going to use ? ForCopyOfKey or just forKey ? Would you want
to upgrade that with takeValue:forCopiedKey: ?
Would you not now in 99% of all cases write forCopyOfKey in your code ?
Well you probably wouldn't, but most others would I bet. Don't you want
more init methods too now ?
Is this idea good ? You gained flexibility, but not without loss. You
made the interface more complicated. Dictionaries can still be
corrupted by NSMutableStrings, so they have been weakened. Your "design
decision". Not a good idea IMO.
Wouldn't it be easier to fix your problem by writing (THAT is a
workaround.)
- (id) copyWithZone:(NSZone *) uselessZone
{
return( [self retain]);
}
in your mutable class, whose instances you want to use as a key for
NSDictionary - instead of using NSMapTable which is intended for that
usage - and live dangerously ?
Not true.
True. (s.a.)
Idiotentennis.
It would take two idiots to actually play tennis.
Second serve. Mr. Weiher.
This becomes a matter of statistics. Ponder on this: If your machine
produces lets say thousand keys a second, where only 0.1 promille is
mutable.
Maybe your programs are random string/mutable-string generators. Mine
aren't.
Sorry that it wasn't plainly enough written for you to deduce the point.
That is left as an exercise for the student. [Hint: look just above
this section at your own reasoning]
Looks fine.
Let's play a little game, it's called "odd one out".
NSSet - client copies, if necessary
NSArray - client copies, if necessary
NSDict value - client copies, if necessary
NSDict key - dict copies, always
Can you tell which one is different?
Well can you figure out where in these classes you are want to store an
individual object and where you are keeping an index together with one
?
NSDictionary as specified is using -hash and -isEqual:
Yes, and NSObject provides implementations, and the docs for hash
(which were posted here before) actually says that the hash it is
doing (independent of value!) is a good one for mutable objects placed
in collections!
It actually says that mutable objects in collections are dangerous.
NSObject doesn't have any values outside of it's retain count and its
isa. The only thing it has otherwise is the address. So guess what is
used as hash and to compare with isEqual: ? The hash is only "good" in
the sense that it spreads your objects fairly evenly over the range of
internal buckets. Since with mutable objects, you have to be content
with pointer equality to be safe, this and the default implementation
of NSObject isEqual: is good enough.
Otherwise your hash and isEqual: would be varying. You MUST override
NSObject's hash if you override isEqual: to test for anything else than
pointer equality.
Mutable objects in collections that exhibit varying hash and isEqual:
like NSMutableString break things:
NSMutableSet *set;
NSMutableString *s;
set = [NSMutableSet set];
s = [@"foo" mutableCopy];
[set addObject:s];
[s appendString:@"bar"];
[set addObject:s];
NSLog( @"%@", set); // hoppla same object twice in NSSet, but both
objects are isEqual:
Guess what other objects implement to determine if two objects are
considered equal. Isa ? Retaincount ? The address ? Nope. (The
address equality you check with == ). They use their values to
determine equality. As all the values are by the protocols definition
identical just after the copy, isEqual: and hash will match up.
BTW: Which object does not implement copyWithZone: and can not be used
as a NSDictionary out of the box ? NSObject. No coincidence.
Or differently, why do you think the rationale for a NSCopying
protocol is there in the first place ?
I have never seen a rationale for the NSCopying protocol, and quite
frankly, find it somewhat superfluous.
I think the rationale for the existence of NSCopying goes hand in hand
with the distinction of immutable and mutable classes. As certain
classes wanted to have their private immutable copies of parameters.
Like accessors, like NSDictionary....
Ciao
Nat!
------------------------------------------------------
Opposites attract.
Then they kill each other. -- Conley
_______________________________________________
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: | |
| >Ugly bug in Foundation, beware! (From: Ondra Cada <email@hidden>) |
| >Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Alastair Houghton <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Ondra Cada <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Alastair Houghton <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Brent Gulanowski <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Alastair Houghton <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Ondra Cada <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Marcel Weiher <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Brent Gulanowski <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: "Louis C. Sacha" <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Marcel Weiher <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Nat! <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Marcel Weiher <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Nat! <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Marcel Weiher <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Nat! <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Marcel Weiher <email@hidden>) |