NSMapTable and NSMutableDictionary differences
Asked Answered
T

4

13

Is an NSMapTable the same as an NSMutableDictionary except for allowing keys to be pointers?

Does it differ in memory management?

Technetium answered 1/8, 2011 at 21:13 Comment(0)
W
-5

The main difference between NSMapTable and NSMutableDictionary is that NSMapTable stores weak pointers. This means that when you call smth like this:

[my_table setValue: val forKey: key];

the value and key are not retained (it means no retain message is sent to them). That's why you can use any object (or maybe not object but any pointer) cause they don't have to respond to retain message.

So you probably want to use NSMapTable if you're using garbage collection where you don't need to bother about retain count of an object.

Weig answered 1/8, 2011 at 21:43 Comment(1)
It isn't always the case that NSMapTable uses weak pointers, the code that initializes the map table actually gets to pick between many different combinations of pointer strength and equality style.Anthropocentric
F
26

NSMapTable is more flexible than NSDictionary. While NSDictionary keeps strong references for values and copies the keys, you can configure NSMapTable to have any of those behaviors independently for objects and values: strong, weak or copy (more behavior options exist).


A practical use case: an NSDictionary keeps a strong reference (retains) of the pointer of the value, but copies the key. This means a) the key instance must implement the NSCopying protocol and b) depending on the complexity of the class, copying might add an overhead. On the other hand, you can configure an NSMapTable to act like an NSDictionary that uses strong references for both the values and the keys, no copying or NSCopying protocol needed.

An object-to-object behavior could previously be emulated using an NSDictionary if all the keys were NSNumbers containing the memory address of the source object in the mapping (don't laugh, I've seen it done) but outside of this run-around, NSMapTable offers a true object-to-object mapping for the first time in a Cocoa collection class.

(From a great article covering NSMapTable when it was introduced.)

Let's look at the API. This will return an object that works much the same as an NSMutableDictionary:

[NSMapTable mapTableWithKeyOptions:NSMapTableCopyIn
                      valueOptions:NSMapTableStrongMemory]

This will return an object that works doesn't copy the keys:

[NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory
                      valueOptions:NSMapTableStrongMemory]

Note: It looks like the NSMapTable API has changed in recent SDKs, but this syntax seems to be compatible with all SDKs.

NSMapTable is available on OS X 10.5+ and iOS 6.0+.

Feininger answered 29/8, 2012 at 20:52 Comment(1)
Why does NSMapTable seem to compile and work when I deploy to an iOS 5.1 device?Juvenilia
F
3

More or less, it has some additional options that are primarily relevant if you use Garbage Collection (which is sort of deprecated, I guess). If you don't use Garbage Collection, the memory management requirements are the same.

Another difference is that NSMapTable can optionally use pointer equality for hashing.

Faucher answered 1/8, 2011 at 21:42 Comment(0)
S
0

Be aware that NSMapTable sometimes not deallocates keys and objects if weak-weak, weak-strong or strong-weak bindings are used http://cocoamine.net/blog/2013/12/13/nsmaptable-and-zeroing-weak-references/.

Also in NSMapTable.h you can find that 'entries are not necessarily purged right away when the weak key is reclaimed' :

+ (id)weakToStrongObjectsMapTable NS_AVAILABLE(10_8, 6_0); 
// entries are not necessarily purged right away when the weak key is reclaimed
+ (id)weakToWeakObjectsMapTable NS_AVAILABLE(10_8, 6_0); 
// entries are not necessarily purged right away when the weak key or object is reclaimed
Sniffy answered 16/9, 2014 at 11:51 Comment(0)
W
-5

The main difference between NSMapTable and NSMutableDictionary is that NSMapTable stores weak pointers. This means that when you call smth like this:

[my_table setValue: val forKey: key];

the value and key are not retained (it means no retain message is sent to them). That's why you can use any object (or maybe not object but any pointer) cause they don't have to respond to retain message.

So you probably want to use NSMapTable if you're using garbage collection where you don't need to bother about retain count of an object.

Weig answered 1/8, 2011 at 21:43 Comment(1)
It isn't always the case that NSMapTable uses weak pointers, the code that initializes the map table actually gets to pick between many different combinations of pointer strength and equality style.Anthropocentric

© 2022 - 2024 — McMap. All rights reserved.