Re: problem with subclassing a cluster class
Re: problem with subclassing a cluster class
- Subject: Re: problem with subclassing a cluster class
- From: Greg Herlihy <email@hidden>
- Date: Sun, 05 Mar 2006 13:07:21 -0800
- Thread-topic: problem with subclassing a cluster class
See comments below...
On 3/5/06 12:18 PM, "Ivan Kourtev" <email@hidden> wrote:
> Hi,
>
> I want to subclass NSDictionary so that I can override -
> (NSScriptObjectSpecifier *)objectSpecifier to make my app
> scriptable. I understand that NSDictionary is a class cluster so I
> follow the prescriptions in Apple's document "Cocoa Objects", the
> chapter on class clusters. I am trying to use the "Composite Object"
> pattern (to be honest, I didn't fully understand the difference
> between this and the "True Subclass" pattern because they are both
> derived from the cluster so seem like subclasses).
>
> At any rate, my problems seem to arise from the fact that I want to
> initialize an instance of my subclass with the variadic function +
> (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...
>
> From everything I have read and tried, it appears that I cannot
> simply pass the arg list of a variadic function to another variadic
> function within it. So I went for something like the code attached
> at end -- compiles with no warnings but I get an *** Uncaught
> exception: <NSInternalInconsistencyException> *** -[NSCFDictionary
> setObject:forKey:]: mutating method sent to immutable object at runtime.
Since the dictionary is immutable, your routine must initialize it with a
single call. The NSDictionary's entries cannot be added one at a time like
your current code is doing. And that is the behavior causing the problem.
Therefore I would recommend pre-allocating two reasonably-sized C arrays,
one to hold the keys and the other to hold the values. Then I would place
each key and value in the corresponding array as they are read in (with the
usual precautions: being certain to use large enough arrays and checking
that the current index is within a valid range).
Only after all the parameters have been processed in this way, would I call
- (id)initWithObjects:(id *)objects forKeys:(id *)keys
count:(unsigned)count;
Passing pointers to the key and value arrays and how many items are in
either - for the count.
> So I try changing NSDictionary to NSMutableDictionary and things only
> start working somewhat when I also derive MyDictionary from
> NSMutableDictionary. But now I get runtime errors like *** Uncaught
> exception: <NSInvalidArgumentException> *** -count only defined for
> abstract class. Define -[MyDictionary count]! and I keep fixing them
> but a new one keeps popping in (count, keyEnumerator, etc.)
I would advise going back to the original design - inherit from NSDictionary
but use the algorithm I described above.
> Is the overriding of all these methods something I really should do
> or am I missing something here? In rereading the Apple doc
> referenced above "Since the cluster¹s abstract superclass is the only
> publicly visible node in the cluster¹s hierarchy, the first point is
> obvious. This implies that the new subclass will inherit the
> cluster¹s interface but no instance variables, since the abstract
> superclass declares none. Thus the second point: The subclass must
> declare any instance variables it needs. Finally, the subclass must
> override any method it inherits that directly accesses an object¹s
> instance variables. Such methods are called primitive methods." so
> may be I should really redefine all primitive classes?
>
> But then, two other points in question:
>
> 1. How does one tell which methods of a class cluster are primitive
> and which aren't?
The intro section of the Objective-C class reference documentation will tell
you. They are also the first routines to appear in the header file and are
set apart from the others. For NSDictionary, there are only three primitive
methods (they are count, keyEnumerator and objectForKey:)
> 2. Assuming I pulled it off, my non-mutable dictionary class is still
> based on NSMutableDictionary which just doesn't seem right? This
> feels like a contradiction to me -- there has to be a more elegant
> solution here that I can't see. Help anyone?
In essence your dictionary class is mutable, even if you don't want to admit
it :-). But inheriting from NSDictionary is much more pleasant an experience
(once you know how) and will work out better anyway.
Greg
_______________________________________________
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