I'm using NSMapTable
in a number of places in an iOS 6 project, and would like to be able to use the new dictionary subscripting style for accessing objects. (NSMapTable
behaves mostly like an NSMutableDictionary
, but can be configured with various memory management options for the keys and values it stores. More background in this StackOverflow question.)
The compiler reports this when attempting to use subscripting syntax on an NSMapTable
instance:
Expected method to read dictionary element not found on object of type 'NSMapTable *'.
How can I use a category to extend NSMapTable
to allow the new NSDictionary
-style subscripting?
NSDictionary / NSMutableDictionary copies keys, and holds strong references to values. NSMapTable is mutable, without an immutable counterpart. NSMapTable can hold keys and values with weak references, in such a way that entries are removed when either the key or value is deallocated.
A collection similar to a dictionary, but with a broader range of available memory semantics. iOS 6.0+ iPadOS 6.0+ macOS 10.5+ Mac Catalyst 13.1+ tvOS 9.0+ watchOS 2.0+
Creating NSDictionary Objects Using Dictionary Literals In addition to the provided initializers, such as init(objects:forKeys:) , you can create an NSDictionary object using a dictionary literal. In Objective-C, the compiler generates code that makes an underlying call to the init(objects:forKeys:count:) method.
An object representing a dynamic collection of key-value pairs, for use instead of a Dictionary variable in cases that require reference semantics.
The answer's actually simple; see this question for more information about how subscripting is implemented. Add a category like this.
Header:
@interface NSMapTable (Subscripting)
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key;
- (id)objectForKeyedSubscript:(id)key;
@end
Implementation:
@implementation NSMapTable (Subscripting)
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key {
[self setObject:obj forKey:key];
}
- (id)objectForKeyedSubscript:(id)key {
return [self objectForKey:key];
}
@end
This makes me wonder, for a moment, whether subscript access is actually a tiny bit slower than the alternative in some or all cases, but the words "premature optimization" make that thought inconsequential.
Improved @mjh answer with NSDictionary
's behavior on setting object for nil
key and added Obj-C Generics:
@interface NSMapTable<KeyType, ObjectType> (Subscripting)
- (void)setObject:(ObjectType)obj forKeyedSubscript:(KeyType)key;
- (ObjectType)objectForKeyedSubscript:(KeyType)key;
@end
@implementation NSMapTable (Subscripting)
- (void)setObject:(id)obj forKeyedSubscript:(id)key {
if (object) {
[self setObject:obj forKey:key];
} else {
[self removeObjectForKey:key];
}
}
- (id)objectForKeyedSubscript:(id)key {
return [self objectForKey:key];
}
@end
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