Subscripting syntax for NSMapTable in iOS 6
Asked Answered
K

2

5

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?

Katharynkathe answered 31/10, 2012 at 0:51 Comment(0)
K
5

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.

Katharynkathe answered 31/10, 2012 at 1:11 Comment(3)
IMO, this is not a good idea. NSMapTable doesn't have subscripting for a reason. For example, if you've got a NSMapTable using NSPointerFunctionsStrongMemory, why would you need to conform to NSCopying? This category actually cripples NSMapTable to a dictionary-like collection.Cabot
@RudolfAdamkovic you can avoid usage of NSCopying in the subscription methods declarations.Hetman
One of the advantages of the NSMapTable is that it does not require the objects to conform to the NSCopying protocol. So it makes no sense to add it to the category implementation.Cloak
H
2

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
Hetman answered 17/2, 2017 at 13:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.