【发布时间】:2011-08-01 21:13:00
【问题描述】:
除了允许键是指针之外,NSMapTable 是否与 NSMutableDictionary 相同?
内存管理有区别吗?
【问题讨论】:
标签: objective-c cocoa nsmutabledictionary
除了允许键是指针之外,NSMapTable 是否与 NSMutableDictionary 相同?
内存管理有区别吗?
【问题讨论】:
标签: objective-c cocoa nsmutabledictionary
NSMapTable 比 NSDictionary 更灵活。虽然 NSDictionary 为值保留强引用并复制键,但您可以将 NSMapTable 配置为具有独立于对象和值的任何这些行为:强、弱或复制(存在更多行为选项)。
一个实际用例:一个 NSDictionary 保持对值指针的强引用(保留),但 复制 键。这意味着 a) 关键实例 必须 实现 NSCopying 协议和 b) 根据类的复杂性,复制可能会增加开销。另一方面,您可以将 NSMapTable 配置为像 NSDictionary 一样对值 和 键使用强引用,无需复制或 NSCopying 协议。
对象到对象的行为以前可以使用 NSDictionary 如果所有键都是包含内存的 NSNumbers 映射中源对象的地址(别笑,我看过 完成)但在此运行之外,NSMapTable 提供了一个真正的 Cocoa 集合中的第一次对象到对象映射 类。
(来自a great article covering NSMapTable when it was introduced。)
让我们看看 API。这将返回一个与 NSMutableDictionary 工作方式非常相似的对象:
[NSMapTable mapTableWithKeyOptions:NSMapTableCopyIn
valueOptions:NSMapTableStrongMemory]
这将返回一个不会复制键的对象:
[NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory
valueOptions:NSMapTableStrongMemory]
注意:NSMapTable API 似乎在最近的 SDK 中发生了变化,但这种语法似乎与所有 SDK 兼容。
NSMapTable 适用于 OS X 10.5+ 和 iOS 6.0+。
【讨论】:
或多或少,如果您使用垃圾收集,它有一些主要相关的附加选项(我猜这是不推荐使用的)。如果不使用垃圾回收,内存管理要求是一样的。
另一个区别是NSMapTable 可以选择使用指针相等性进行散列。
【讨论】:
请注意,如果使用弱-弱、弱-强或强-弱绑定http://cocoamine.net/blog/2013/12/13/nsmaptable-and-zeroing-weak-references/,NSMapTable 有时不会释放键和对象。
同样在 NSMapTable.h 中你可以发现 '在回收弱密钥时不一定会立即清除条目':
+ (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
【讨论】:
NSMapTable 和 NSMutableDictionary 的主要区别在于 NSMapTable 存储的是弱指针。这意味着当你这样调用 smth 时:
[my_table setValue: val forKey: key];
不保留值和键(这意味着没有保留消息发送给它们)。这就是为什么您可以使用任何对象(或者可能不是对象而是任何指针),因为它们不必响应保留消息。
因此,如果您正在使用垃圾收集而不需要担心对象的保留计数,那么您可能希望使用 NSMapTable。
【讨论】: