Subclassing NSMutableDictionary
Asked Answered
S

3

13

I am trying to implement a subclass of NSMutableDictionary that returns nil instead of throwing a NSUndefinedKeyException when the key is not present in the Dictionary.

However when I try to add objects to my dictionary I get

[NSMutableDictionary setObject:forKey:]: method only defined for abstract class

NilDictionary.h

@interface NilDictionary : NSMutableDictionary {
} 
@end

NilDctionary.m

@implementation NilDictionary
- (id)valueForUndefinedKey:(NSString *)key {
  return nil;
}
@end

Do I really have to implement all the methods from NSMutableDictionary again in my subclass or is there some other class I should be subclassing?

Clarification: My original problem came down to me not being able to read the documentation properly.

If you need to subclass NSMutableDictionary check out the correct answer. If you want a dictionary that returns nil when your key is not present, NSMutableDictionary does that already.

Sumikosumma answered 25/1, 2011 at 4:2 Comment(1)
What exactly are you doing with a dictionary to cause it to throw an NSUndefinedKeyException? Trying to access an invalid key in a dictionary automatically returns nil anyways; how are you getting this error?Branchiopod
C
26

NSMutableDictionary Class Reference says:

In a subclass, you must override both of its primitive methods:

1. setObject:forKey:
2. removeObjectForKey:

You must also override the primitive methods of the NSDictionary class.


NSDictionary Class Reference says:

If you do need to subclass NSDictionary, you need to take into account that is represented by a Class cluster—there are therefore several primitive methods upon which the methods are conceptually based:

1. count
2. objectForKey:
3. keyEnumerator
4. initWithObjects:forKeys:count:

In a subclass, you must override all these methods.

NSDictionary’s other methods operate by invoking one or more of these primitives. The non-primitive methods provide convenient ways of accessing multiple entries at once.


It seems that you need to override all these six methods to make your NSMutableDictionary subclass work perfect.

Caustic answered 25/1, 2011 at 4:17 Comment(1)
You must also override initWithObjects:forKeys:count:Estheresthesia
B
4

Here's your problem. NSDictionary (and its mutable counterpart) is part of a class cluster (read more about them here, under the 'Class Cluster' heading), and should not be subclassed because it causes problems such as what you've mentioned (read the subclassing notes in the NSDictionary Class Reference). Whatever it is you need to do, you're going to have a way to extend the classes you want to use in order to do what you want to do. For instance, the above code can easily be placed in a category (read more about categories here).

Branchiopod answered 25/1, 2011 at 4:13 Comment(3)
Thanks for the heads up. It seems that to subclass a Class Cluster I just need to implement all primitive methods. For NSMutableDictionary this means that I also need to write a simple implementation for * count * objectForKey: * keyEnumerator * setObject: forKey: * removeObjectForKey: I'm hesitant to use a category because as I understand it that would affect every use of NSMutableDictionary within my application?Sumikosumma
Also, I don't know what you're doing wrong, but when you try to access a key not found in a dictionary, it returns nil anyway; it doesn't throw an NSUndefinedKeyException... What is it exactly you are trying to do?Branchiopod
Thanks. I probably should have just tried it instead of looking for it in the documentation.Sumikosumma
M
-2

Are you sure you are not getting the exception when passing in "nil" for a KEY (not a value)?

Morbific answered 25/1, 2011 at 4:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.