Re: NSDictionary design bug (was: Re: Ugly bug in Foundation, beware!)
Re: NSDictionary design bug (was: Re: Ugly bug in Foundation, beware!)
- Subject: Re: NSDictionary design bug (was: Re: Ugly bug in Foundation, beware!)
- From: Andy Lee <email@hidden>
- Date: Mon, 7 Jun 2004 22:51:53 -0400
I haven't read every word in this thread, but occasionally I spot a
sentence that swings my opinion one way or the other. I'm glad the
strong emotions haven't bubbled over too far.
On Jun 7, 2004, at 3:13 PM, Christian Brunschen wrote:
There's been a lot of debate on this issue; I'm going to be horrible
and
actually propose a change that might make everyone a bit happier!
I'm glad to see a proposal in the spirit of bringing us all together...
3) Let The Object Decide
[...]
By introducing a new protocol, I'll call it 'NSDictionaryKey' for this
discussion, each object could be asked for the correct behaviour -
whether
to use the object directly, whether the object needs to be copied, and
so
on. Something like this:
@protocol NSDictionaryKey
- (id) replacementKeyForDictionary:(NSDictionary *)dict;
@end
For all the reasons you give, I think it makes a lot of sense to
decouple the "what-to-use-as-key" concept from the "copy" concept.
I would like to suggest an alternate approach to "Letting The Object
Decide" that allows the decision making to be divided up into different
methods for different cases, instead of always being funneled through
-replacementKeyForDictionary:. My idea is to put flexibility in the
dictionary class.
NSDictionary could have a new designated initializer that specifies a
key-creation method and a key-equality-testing method:
- (id)initWithKeyCreator:(SEL)keyCreator
equalityTester:(SEL)equalityTester;
If NULL is given as keyCreator, the dictionary uses the default
behavior you described for -replacementKeyForDictionary:, namely:
if ([theGivenKey conformsToProtocol:@protocol(NSCopying)])
{
// use [theGivenKey copy] as the internal key
}
else
{
// use theGivenKey as the internal key
}
Otherwise, keyCreator must refer to a no-argument message that every
key object must respond to.
If NULL is given as equalityTester, the dictionary uses == to compare
keys. Otherwise, equalityTester must refer to a single-argument method
that behaves like -isEqual:.
If you want your dictionary to be entirely reference-based, you can do
this:
myDictionary =
[[NSMutableDictionary alloc]
initWithKeyCreator:@selector(self)
equalityTester:(SEL)NULL];
If you want your dictionary to be entirely value-based, using your own
method for snapshotting an object's value, you can do this:
myDictionary =
[[NSMutableDictionary alloc]
initWithKeyCreator:@selector(myDeepCopy)
equalityTester:@selector(isEqual:)];
The nice thing about this solution is that it can actually be
retrofitted
onto the existing Cocoa frameworks without breaking anything.
I think the same is true of my suggestion if the -init method for
NSDictionary is rewritten to look like this:
- (id)init
{
return
[self
initWithKeyCreator:(SEL)NULL
equalityTester:@selector(isEqual:)];
}
It would be interesting to actually write the code we've been proposing
and drop it into an existing application using +poseAsClass:.
If you've managed to read to the end of this post, then I hope I
haven't
bored you too badly :) Please do feel free to comment on the above.
Keep
in mind that this is just typed directly into this email from my
somewhat
disorganized mind, so there are bound to be errors, and I'm glad to
have
them identified and pointed out, so they can be corrected.
Ditto!
--Andy
_______________________________________________
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.