Is an NSMapTable
the same as an NSMutableDictionary
except for allowing keys to be pointe开发者_如何学Gors?
Does it differ in memory management?
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+.
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.
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
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.
精彩评论