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.
The NSMutableDictionary class declares the programmatic interface to objects that manage mutable associations of keys and values. It adds modification operations to the basic operations it inherits from NSDictionary . NSMutableDictionary is “toll-free bridged” with its Core Foundation counterpart, CFMutableDictionary .
Use -mutableCopy . NSDictionary *d; NSMutableDictionary *m = [d mutableCopy]; Note that -mutableCopy returns id ( Any in Swift) so you will want to assign / cast to the right type. It creates a shallow copy of the original dictionary.
[myDictionary setObject:nextValue forKey:myWord]; You can simply say: myDictionary[myWord] = nextValue; Similarly, to get a value, you can use myDictionary[key] to get the value (or nil).
In general, the collection classes (for example, NSMutableArray , NSMutableDictionary ) are not thread-safe when mutations are concerned. That is, if one or more threads are changing the same array, problems can occur.
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With