• 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: Can a subclass of NSDictionary do this?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Can a subclass of NSDictionary do this?


  • Subject: Re: Can a subclass of NSDictionary do this?
  • From: Greg Titus <email@hidden>
  • Date: Tue, 22 Jul 2003 16:11:06 -0700

On Tuesday, July 22, 2003, at 03:36 PM, James Quick wrote:
I was implementing a subclass of NSObject which contained an NSMutableDictionary.
The purpose is to support a storage container for nested NSDictionaries to allow me to
search by keys having internal structure.

for a call [self lookup: k inDict: d]

The key@ "a.b.c" would do the following
lookup: k inDict: d
v = [d objectForKey: @"a"]
if ([v isKindOfDictionary])
return [self lookup: @"b.c" inDict: d]
else return v;

this would reduce to looking up @"c" in the subdictionary @"a.b"
Thus a single call to lookup would traverse a path through the set of nested dictionaries to find a value.

This is built in actually. Look at the documentation for NSKeyValueCoding. Specifically, you'll get exactly the result you want by calling [d valueForKeyPath:@"a.b.c"].

If this didn't already exist, the best way to implement it would be the way Apple did it: as a category on existing classes. If you find yourself wanting to add methods but not instance variables to a class (or classes) writing categories should almost always be your first choice.

Then I encountered some documentation that made me wonder.

The documentation for NSDictionary states:
"NSDictionary's three primitive methods- count, objectForKey:, and keyEnumerator-provide the basis for all of the other methods in its interface."

The NSMutableDictionary documentation declares:
"With its two efficient primitive methods- setObject:forKey: and removeObjectForKey:-this class adds modification operations to the basic operations it inherits from NSDictionary."

This made me wonder if I could simply override 5 methods, with recursive implementations
and be able to make use of all the other functionality of those classes for free!

Yes, you can, but it usually isn't recommended. Read the documentation on "Class Clusters".

Imagine that I have a subclass of NSDictionary which declares no new instance variables
overrides objectForKey. Lets call this RDict for recursive dict. and Dict for an NSDictionary

Is there way via casting, or other mild chicanery, to cause a vanilla NSDictionary or
NSMutableDictionary instance to rely on my implementation of a few methods,
and have the rest handled by calls to super?

You'd do this via -poseAs:. (NSObject documentation.)


I could then take dictionaries loaded by CFPreferences, for instance and
get the recursive path lookups for nearly no work. Simply by tricking them
temporarily into thinking they were instances of my class.

I thought of categories but I would prefer another approach, because I don't want to
impose the added overhead on all instances of NSDictionary.

There is absolutely no added overhead with categories.

Would [((MyClass *)plainClass) objectForKey] start its method lookup
in the isa of MyClass or the isa of [plainClass class].

Casting Obj-C objects does nothing. It compiles into no code and doesn't change the semantics at all. The only reason why it is useful is to tell the compiler that you are doing something, so that it knows whether to give you warnings about messages going to wrong classes and the like.

Or could I safely do (yes I know this looks scary)

Class * cheatLikeHell(struct objc_object *object, Class *otherclass)
{
Class *oldClass = object->isa;
object->isa = otherclass;
return oldClass;
}

Class *customClass = [MyRecursiveDictionary class];
Class *savedClass = cheatLikeHell(normalDictionary, customClass);
[normalDictionry doStuff]; // now using my implementation
(void) cheatLikeHell(normalDictionary, savedClass);

Yes, you could, but it is _so_ much simpler to just add a category with a -myDoStuff method and call that instead.

Hope this helps,
- Greg
_______________________________________________
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: 
 >Can a subclass of NSDictionary do this? (From: James Quick <email@hidden>)

  • Prev by Date: flummoxed by math failure
  • Next by Date: Re: Button IB action on rename
  • Previous by thread: RE: Can a subclass of NSDictionary do this?
  • Next by thread: Re: Can a subclass of NSDictionary do this?
  • Index(es):
    • Date
    • Thread