Re: Know about Mutability
Re: Know about Mutability
- Subject: Re: Know about Mutability
- From: Shawn Erickson <email@hidden>
- Date: Fri, 14 Jan 2005 09:22:02 -0800
On Jan 14, 2005, at 4:34 AM, Paul Sargent wrote:
Peter Maurer wrote:
Perhaps I over-trimmed -- the context was "But how do I know
whether myDict is mutable or not?". Testing for
isKindOfClass:[NSMutableDictionary class] does not work as you
might expect...
I'm confused about why respondsToSelector: isn't working
correctly... Either the object will handle the selector (and
respondsToSelector: returns true) or it doesn't and respondsTo
returns false?
Or is this object somehow not strictly an Objective C object and
therefore doesn't properly handle respondsToSelector but actually
properly handles the setObject:forkey: message? Or... ?
You can rephrase Mmalcolm's statement as follows: Subclasses of
NSMutableDictionary are not necessarily mutable. (NSCFDictionary is
obviously a subclass of NSMutableDictionary -- AFAIK, cocoa's
dictionary classes are all subclasses of NSMutableDictionary, even
though that's not what the documentation says.)
Sounds to me like the design of these classes is backwards.
I was always taught that if you made a sub-class of a super-class,
then the sub-class had to support all of the methods of the
super-class. therefore preserving the 'is-a' paradigm (sp?). In this
case a NSMutableDictionary 'is-a' NSDictionary, but the same cannot be
said the other way round. Overriding methods to raise exceptions
sounds like a hack because of this.
Is there a good reason that NSDictionary inherits from
NSMutableDictionary, rather than the other way round?
NSDictionary does NOT inherit form NSMutableDictionary check the
headers.
What is going on is that Cocoa is a runtime bound language such that
you can send any message to any object (it may not support it but you
can try), also objects can proxy, act, etc. as another object and
NSDictionary and relatives are implemented as class clusters.
In this case all instances of NSDictionary and NSMutableDictionary
return instances of a common class (NSCFDictionary) configured as
needed (this is perfectly legal in Objective-C, why the init messaging
semantics are as they are for example). This class is also toll free
bridged with the common structure that CFDictionary/CFMutableDictionary
use (non-object based dictionary functions).
If you do a CFShow on a recast of your NSDictionary or
NSMutableDictionary instance you will see that it notes if the class is
consider mutable or not (doing so with NSLog may do the same, I haven't
tried). In other words the implementing class provides all methods
needed by NSDictionary and NSMutableDictionary but a flag in the
object/structure itself denotes how it should behave. If you think
about how toll free bridging works (just a cast away) and how CF is
implemented you can see the source of the issue comes from how CF is
implemented, it uses one structure with a flag difference to implement
both CFDictionary and CFMutableDictionary so Cocoa has to bridge that
struct with an object of a single class.
The problem is that the setting of this flag isn't cleanly or easily
exposed by the traditions methods like isKindOf, respondsToSelector,
etc. at this time. Apple could address this in various ways with
various levels of potential backwards compatibility issues (depending
on quirks / assumptions in existing code). It may be best to provide a
universal isMutable method on NSObject (or course that has backwards
compatibility issues with any one that has added such a method via a
category ect.) that can be used to understand in one shot if an object
is or isn't mutable.
So yeah this does make it hard to know if a instance of dictionary is
mutable or not without messaging one of the mutable methods, in my
opinion and in practice the first good solution to this is to change
your code to not need to depend on knowing about mutability.
-Shawn
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden