• 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: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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: Sun, 6 Jun 2004 21:32:08 +0200

Am 06.06.2004 um 14:13 schrieb Marcel Weiher:

On 5 Jun 2004, at 17:49, Nat! wrote:
Am 05.06.2004 um 16:00 schrieb Marcel Weiher:
First, there is *nothing* whatsoever in the behavior of a dictionary, in general CompSci terms, that says its keys should be copied. A dictionary is simply a mapping of keys to values. I have never seen either a definition of dictionary or an implementation that does the copying (apart from this one).

The practical reason for copying

You are replying to the theoretical reasoning with a practical argument, but have snipped the practical reasoning. Anyway...

On the basis of theory, I could also say that there is nothing that forbids it being copied. No ?


is, that in 95% of all cases the keys of dictionaries are strings.

And roughly 100% of those will be strings that do not change afterwards, wether they are constant strings or not. If you design your class in such a way that it assumes (and almost requires) string keys, then it should be called a NSStringDictionary. And 95% of all statistics are made up out of thin air on the spot ;-)

Well the rest 4% are going to be NSDatas and NSNumbers probably :)


Having mutable objects as keys is of course a pandaras box of errors,

This is a theoretical fear. It isn't an practical problem.

Yeah sure. As long as you can pass in mutable strings as keys, and have them be changed outside of the NSDictionary it is a practical problem. I mean if that isn't a practical problem. I don't know what is.

I can't believe that you are unaware that this:

- (void) takeAString:(NSString *) s
{
[lut_ setObject:[NSCalendar date]
forKey:s];
}

will create a hard to trace bug, if someone happens to pass in s as a mutable string and changes the contents after calling takeAString:. How could you harden this code ? The only way is this, bloating the user code (many places instead of one place (NSDictionary)):

- (void) takeAString:(NSString *) s
{
[lut_ setObject:[NSCalendar date]
forKey:[[s copy] autorelease]];
}

I think reading stringValue from a AppKit field editor gives you a mutable string for example. I remember running into that problem early on :)

therefore the key gets copied.

You conveniently snipped my analysis of this part, so here it goes again:

- copying the key is unnecessary, because you can easily specify that requirement in the contract

How would you do that in Foundation ? Only by documentation, not very safe...
Also this would "bloat" client code.

- copying the key is unnecessary, because (string) keys typically won't change, even if they theoretically could

Exactly. Typically(!) they wont change. But I already wrote something about that...

- copying the key does not solve the problem, because copied items can still change under you

But it solves the problem for the highest frequency key classes, NSData, NSNumber and NSString.



As we know, copy on immutable objects is usually just a retain.

Relying on a property of objects

What's the problem with that ?


This retain would have to be done anyway, if you are not copying.

So it is not a design bug but a design choice and a good one.

In a word: no.

It is not a good design choice because it

(a) attempts to solve a problem that DOES NOT EXIST, practically
(and in fact pretty much relies on it not existing in the first place!)

Does exist. You even say it doesn't appear "typically".

(b) then goes on to not actually solving the blasted problem

Does solve it for the vast majority of uses and usually at no extra cost!

(c) prevents uses of the class that are perfectly legitimate for a dictionary

Yup, if it can't be copied it isn't served by NSDictionary. No problem, as NSMapTable is there.

(d) where other solutions exist that work at least as well if not better without introducing these problems

???

Second, the definition is a mapping of (object) keys to values. NOT of the key's value to a value. Since one of the fundamental properties of objects is that they have identity (See RM-ODP and other definitions of the term), the fact that a *different* object is actually used as a key is, at the very least, an odd choice.

By that reasoning you would create two entries for

[dictionary setObject:@"foo"
forKey:[@"bar" mutableCopy]]; // yeah, leak, so what
[dictionary setObject:@"xxx"
forKey:[@"bar" mutableCopy]];

No.

What do you mean no ? How would that not create two entries ?


With the current "design", you impose the constraint that copies must have the same hash and compare equally. Which may not be desirable/feasible. And it is also not documented, as far as I can see.

What would that be good for, in the general case ? As the copy will satisfy the -hash and -isEqual "identity",

Says who?? It certainly isn't listed as a requirement in the NSCopying protocol. Neither is it listed as requirement in NSObject's protocol documentation. In fact, NSObject's implementations -hash and -isEqual: do not satisfy this "identity" you have conjured up out of thin air.

Well thick air. What is the purpose of a copy, if it's isEqual method doesn't find them to be equal. From the dox: "The exact meaning of copy can vary from class to class, but a copy must be a functionally independent object with values identical to the original at the time the copy was made."

If the values are identical, isEqual: failing would be a strange thing indeed. Otherwise we would be back at pointer equality checking (-> two entry problem).


On the other hand the following appears in -hash:

If a mutable object is added to a collection that uses hash values to determine the objects position in the collection, the value returned by the hash method of the object must not change while the object is in the collection. Therefore, either the hash method must not rely on any of the objects internal state information or you must make sure the objects internal state information does not change while the object is in the collection. (Note that it can be difficult to know whether or not a given object is in a collection.)


This actually blatantly contradicts the implementation in NSDictionary!

Well actually both together just state, that if your class is mutable and doesn't convert to immutable when being copied, that you should be extra careful to use it as a key. As this will produce hard to find bugs "(Note that it can be difficult to know whether or not a given object is in a collection.)", someone must have gone down that road before :)

NSMapTable doesn't bite you. Use it. It is also a dictionary in CompSci terms.

Ciao
Nat!
------------------------------------------------------
A good dog, though a fool.
Who wants a smart dog! -- R.A. Lafferty
_______________________________________________
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.


  • Follow-Ups:
    • Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!)
      • From: Marcel Weiher <email@hidden>
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>)

  • Prev by Date: Re: NSDictionary design bug (was: Re: Ugly bug in Foundation, beware!)
  • Next by Date: NSDocument application: How do I maintain a single window?
  • Previous by thread: Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!)
  • Next by thread: Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!)
  • Index(es):
    • Date
    • Thread