[转] NSMapTable 不只是一个能放weak指针的 NSDictionary
NSMapTable 不只是一个能放weak指针的 NSDictionary
NSMapTable是早在Mac OS X 10.5(Leopard)的引入集合类。乍一看,这似乎是作为一个替换NSDictionary的存在,可以选择“strong”和“week”指针。 在这篇文章中,我会告诉你除了为什么它也非常有用之外的还有垃圾回收机制以及它是如何做NSDictionary中不能(或不应该)做的事情。
转至 http://www.isaced.com/post-235.html
Leopard 中更多的Cocoa API
可可增加了几个新的集合类在Mac OS X 10.5(Leopard)的。这些措施包括:
NSPointerArray完全是新的,但大部分的 NSHashTable
和 NSMapTable
的功能之前可从 opaque Foundation C structs of the same names 看到。
在某些方面,这些新的类,像NSMutableArray
, NSMutableSet
和的NSMutableDictionary
一样工作,但是给了你使用“week”垃圾回收指针的选择。如果您使用的 Objective-C 2.0 垃圾回收机制,你应该知道什么是使用“week”指针,因此使用此选项的优势应该是清楚的。
NSPointerArray也可用于纯指针(指针不一定是Objective-C的类),但NSHashTable
和的NSMutableArray
类都需要它们的内容是Objective-C的对象。
虽然在一般意义上,NSPointerArray and NSHashTable 被设计为可以替换 NSMutableArray and NSMutableSet 的角色(有序和无序阵列)。
NSMapTable则是不同的,因为它可以在你的设计中使用,而NSMutableDictionary不能(或不应该)。
NSDictionary的局限性
NSDictionary提供了key-to-object的映射。从本质上讲,NSDictionary中存储的object位置是由“key”来索引的。
由于对象存储在特定位置,NSDictionary中要求key的值不能改变(否则object的位置会突然错误)。为了保证这一点,NSDictionary中始终复制key到它私有位置。
这个key的复制行为也是NSDictionary如何工作的基础,但这也有一个限制:你可以只使用Objective-C对象作为
NSDictionary的key,如果它支持NSCopying协议。此外,key应该是小且高效的,以至于复制的时候不会对CPU和内存造成负担。
这意味着,NSDictionary中真的只有适合“value”类型的对象作为key(如简短字符串和数字)。这不是离线的对象到对象的映射模型。
对象到对象的映射
NSMapTable(顾名思义)更适合于一般意义的映射。这取决于它是如何构造的,NSMapTable可以处理的“key-to-object”样式映射的NSDictionary,但它也可以处理“object-to-object”的映射 - 也被称为“associative array”或简称为“map”。
例如,一个NSMapTable构造如下:
NSMapTable *keyToObjectMapping =
[NSMapTable
mapTableWithKeyOptions:NSMapTableCopyIn
valueOptions:NSMapTableStrongMemory];
将会和NSMutableDictionary工作得一样一样的,复制其“key”,并retaining它的“object”。
一个纯粹的对象到对象(object-to-object)的映射可以构造如下:
NSMapTable *objectToObjectMapping =
[NSMapTable mapTableWithStrongToStrongObjects];
一个对象到对象(object-to-object)的行为可能以前可以用NSDictionary来模拟,如果所有的key都是一个 NSNumber包含于该映射的源对象的内存地址(不要笑,我见过这种情况),但这些内存地址都是奔波在外,Cocoa中首次提供了一个真正的对象到对象 的映射NSMapTable。
NSMapTable的选项
NSMapTable提供的选项是由三部分组成:一个“memory option”(内存选项),一个“personality option”和“copy in”标志。你可以为每个部分使用一个选项(如果没有提供一个选项的部分将会使用默认行为),这个部分都是位标志(bit flag)(二进制 “or” 合并在一起)。
理论上,NSMapTable允许以下选项:
- NSMapTableStrongMemory (a "memory option")
- NSMapTableWeakMemory (a "memory option")
- NSMapTableObjectPointerPersonality (a "personality option")
- NSMapTableCopyIn (a "copy option")
NSMapTableStrongMemory是默认的“memory option”。然而,默认的“personality option”,默认“copy in”的行为没有名字那么这两个值可以被视为隐含在列表中。
memory option
Objective-C使用“strong”和“week”作为垃圾回收机制相关的术语,它可能不是很明显,这些选项可以在垃圾回收机制代码之外使用(苹果称它为手动内存管理)。
在垃圾回收机制外,他们被定义为:
- strong: 使用 retain 和 release
- weak: 不使用 retain 和 release
NSMapTable只允许NSPointerFunctionsOptions对应的Objective-C对象“personality option”。还有其他NSPointerFunctionsOptions “personality option”里的“strong”指针的行为不包括retain和release,但这些选项在NSMapTable都是不允许的。
关于使用垃圾回收机制的“week”之外的警告:
指针将不会被归零如在垃圾回收环境所以你必须要小心,不要取消引用指针,如果它被释放。
Personality options
该NSMapTableObjectPointerPersonality选项用来控制是否isEqualTo:和哈希对象中的方法添加的对象添加到集合时使用。
- NSMapTableObjectPointerPersonality指定
对象的指针的值是用于直接比较和位移哈希生成(isEqualTo:和散列方法是不使用)。 - NSMapTableObjectPointerPersonality 不指定(默认行为)
的哈希值与isEqualTo:方法会在调用的关键在确定的存储位置NSMapTable。这些方法的返回值不应改变(是不可变)为主要用在时间NSMapTable。
两行为暗示内容实现了NSObject
的协议,所以在这个协议方法也可以在key和object调用。特别地,描述的方法可以在被调用NSMapTable包含密钥和对象无论使用的“Personality options”。该NSMapTable
将只支持NSCoding如果所有的key和object实现了NSCoding协议了。
Copy options
如果NSMapTableCopyIn被指定,当NSCopying
协议被加入时NSMapTable
使用使自己的数据副本。如果不指定此选项(默认行为)将不会复制。
翻译自:NSMapTable: more than an NSDictionary for weak pointers
这篇文章虽然很久了(2008年),但就算放在当下也是很有学习价值的,感谢Google translate,感谢Baidu translate!
[转] NSMapTable 不只是一个能放weak指针的 NSDictionary的更多相关文章
- ARC指南1 - strong和weak指针
一.简介 ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain.release.autorelease语句.你不再需要担心内存管理,因 ...
- Delphi动态事件深入分析(对象方法在调用的时候会传递一个隐含的Self指针,而该指针的值在EAX中。即左边第一个参数)
Delphi动态事件深入分析 2009-2-7 作者:不得闲核心提示:本实验证明了在类中方法的调用时候,所有的方法都隐含了一个Self参数,并且该参数作为对象方法的第一个参数传递... 首先做一个空窗 ...
- ARC - strong和weak指针
ARC指南1 - strong和weak指针 提示:本文中所说的"实例变量"即是"成员变量","局部变量"即是"本地变量&qu ...
- ARC指南 strong和weak指针
一.简介 ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain.release.autorelease语句.你不再需要担心内存管理,因为编 ...
- (转)ARC指南 - strong、weak指针
一.简介 ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain.release.autorelease语句.你不再需要担心内存管理,因为编 ...
- Objective-C中,ARC下的 strong和weak指针原理解释
Objective-C中,ARC下的 strong和weak指针原理解释 提示:本文中所说的"实例变量"即是"成员变量","局部变量"即是& ...
- opencv IplImage各参数详细介绍以及如何从一个JPEG图像数据指针转换得到IplImage
这篇文章里介绍得最清楚了.http://blog.chinaunix.net/uid-22682903-id-1771421.html 关于颜色空间 RGB颜色空间已经非常熟悉了.HSV颜色空间需要 ...
- 北冥有 Data,其名为鲲,鲲之大,一个 MySQL 放不下!
千万量级的数据,用 MySQL 要怎么存? 初学者在看到这个问题的时候,可能首先想到的是 MySQL 一张表到底能存放多少条数据? 根据 MySQL 官方文档的介绍,MySQL 理论上限是 (232) ...
- 还是一个关于c++内存指针的问题分析
如果有这么一个结构体 struct win_fd_set { u_int fd_count; SOCKET fd_array[]; }; 这么调用 win_fd_set * Set = (win_fd ...
随机推荐
- (二)Spring 之IOC 详解
第一节:spring ioc 简介 IOC(控制反转:Inversion of Control),又称作依赖注入dependency injection( DI ),是一种重要的面向对象编程的法则来削 ...
- MongoDB权威指南--笔记
mongodb并不具备一些在关系型数据库中很普遍的功能,如连接和复杂的多行事务. 集合-->文档-->id id在文档所属的集合中是唯一的. db.help()查看数据库级别的帮助,db. ...
- 如何让EasyUI弹出层跳出框架
这个的解决方法其实挺简单的. 只要在最外面的框架页面加个div,然后用parent.div的id就可以的.但是必须得弹出框得是一个页面. <div id="div_info" ...
- web_reg_save_param_regexp函数的用法
关联从服务器返回的所有的内容: 本例通过一个使用HTTP/HTML协议发送.获取服务器数据的vuser脚本,分析LoadRunner如何进行HTTP关联. 下面这个例子包括两个事务:上传数据到服务器. ...
- 监控属性数组(Observables Arrays )
如果你想发现并响应一个对象的改变,就应该用监控属性(observables).如果你想发现并响应一个集合的变化,就该用监控属性数组 (observableArray).监控属性数组在显示或编辑多个值以 ...
- Python编程举例-自定义日期格式
#自定义格式 x = '{0}{0}{0}'.format('dog') print(x) class Date: def __init__(self,year, mon,day): self.yea ...
- 【面试总结-编程】多行两列数据,实现同key的value求和并输出
一个文件,两列,多行. 第一列是字母,第二列是数字,同列数据之间通过空格分割. 统计首列字母相同的第二列之和. 样例输入: A 5 B 6 OO 7 A 6 A 2 OO 2 输出: A:13 B:6 ...
- cogs——2098. Asm.Def的病毒
2098. Asm.Def的病毒 ★☆ 输入文件:asm_virus.in 输出文件:asm_virus.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述] “这就 ...
- Linux中用户与组相关配置文件(整理)
用户与组信息存放位置 说明 注释 /etc/passwd 存放用户基本信息 记录了每个用户的一些基本属性,并对所有用户可读,每一行记录对应一个用户,属性之间通过冒号分隔. 每一个行6个冒号,7个属性. ...
- Redis学习篇(八)之连接相关
PING 测试客户端和服务器之间的连接是否有效,有效返回PONG ECHO 打印特定的信息, 如: ECHO 'HELLO WORLD' QUIT/EXIT 断开当前客户端与服务器之间的连接,可以重连 ...