Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subclassing NSMutableDictionary

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.

like image 532
Ben Avatar asked Jan 25 '11 04:01

Ben


People also ask

What is NSMutableDictionary in Swift?

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 .

How do you convert NSDictionary to NSMutableDictionary?

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.

How do you add value in NSMutableDictionary?

[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).

Is NSDictionary thread safe?

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.


2 Answers

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.

like image 134
EmptyStack Avatar answered Nov 15 '22 22:11

EmptyStack


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).

like image 24
Itai Ferber Avatar answered Nov 15 '22 23:11

Itai Ferber