[转] NSMapTable 不只是一个能放weak指针的 NSDictionary

news/2024/7/20 12:38:56 标签: 移动开发, 操作系统, 内存管理

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

NSPointerArray完全是新的,但大部分的 NSHashTableNSMapTable 的功能之前可从 opaque Foundation C structs of the same names 看到。

在某些方面,这些新的类,像NSMutableArrayNSMutableSet和的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!

 

 

 

转载于:https://www.cnblogs.com/YouXianMing/p/3696054.html


http://www.niftyadmin.cn/n/668584.html

相关文章

xml大于等于转移_Mybatis.xml文件中大于小于等于

第一种写法&#xff1a;原符号 < < > > & "替换符号 < < > > & "例如&#xff1a;sql如下&#xff1a;create_date_time > #{startTime} and create_date_time < #{endTime}第二种写法&#xff1a;大于等于 ]]>小于等于例…

ViewDragHelper实战 自己打造Drawerlayout

转载请标明出处&#xff1a; http://blog.csdn.net/lmj623565791/article/details/47396187&#xff1b; 本文出自:【张鸿洋的博客】 一、概述 中间拖了蛮长时间了&#xff0c;在上一篇我们介绍了ViewDragHelper&#xff0c;详情&#xff1a;ViewDragHelper完全解析&#xff…

UVA 725 Division(hash+枚举)

题目大意&#xff1a; 就是说给你一个abcde/fghij n的表达式&#xff0c;给你一个n&#xff0c;让你求出有多少个这样的式子。 解题思路&#xff1a; 最为简单的枚举了&#xff0c;要注意到我们只需要枚举出来fghij就可以了&#xff0c;因为abcdefghij*n,这样的话&#xff0c;…

教你如何追女孩!

【∞江南苑∞】%江南苑%年末精华帖——教你如何追女孩&#xff01;&#xff08;原创&#xff0c;连载&#xff09;【实用】 aberding【品读江南●翰墨流芳】 - 猫扑大杂烩 - 体验年轻 - 猫扑互动中心在MOP混了有些年头&#xff0c;看了不少关于如何追女孩子的帖子&#xff0c;…

SqlServer SSAS IIS 部署

参考MSDN官网&#xff1a;http://technet.microsoft.com/zh-cn/library/gg492140.aspx 注意事项&#xff1a; 网络上有文章说&#xff0c;最后验证是否成功 是在浏览器中输入url地址&#xff0c;有XML结果返回。此说法错误。坑苦了我。如&#xff1a;Win7下IIS 7.5配置SSAS(200…

怪物行为树案例_游戏开发中怪物AI实现方案总结

前言在游戏开发中实现怪物AI逻辑的主要技术有两种&#xff1a;1、状态机2、行为树。 他们两者的实现机制不一样&#xff0c;其中状态机是“事件”机制&#xff0c;行为树是“轮询”机制。在项目开发中可以根据具体情况合理的选择两者来处理AI编写问题。这篇文章分两个部分对游戏…

【3D研发笔记】之【数学相关】(一):坐标系

现在开始学习3D基础相关的知识&#xff0c;本系列的数学相关笔记是基于阅读书籍《3D数学基础&#xff1a;图形与游戏开发》而来&#xff0c;实现代码使用AS3&#xff0c;项目地址是&#xff1a;https://github.com/hammerc/hammerc-Snake3D-as3与https://github.com/hammerc/ha…

vs2013 Release配置

Release版本不要打开运行时检查&#xff0c;否则会降低性能。 多线程DLL是为了和其他编译的裤匹配。 关于LTGC和GL选项的文章&#xff1a; http://blogs.msdn.com/b/vcblog/archive/2009/12/01/gl-and-pgo.aspx http://blogs.msdn.com/b/vcblog/archive/2008/11/12/pogo.aspx转…