本文转自Nidom的博客,原文:《NSHashtable & NSMaptable

 
NSSet, NSDictionary, NSArray是Foundation框架关于集合操作的常用类, 和其他标准的集合操作库不同, 他们的实现方法对开发者进行隐藏, 只允许开发者写一些简单的代码,让他们相信这些代码有理由正常的工作.。
 
然而这样的话最好的代码抽象风格就会被打破,苹果的本意也被曲解了. 在这种情况下, 开发者寻求更好的抽象方式来使用集合,或者说寻找一种更通用的方式。
 
对于 NSSet 和 NSDictionary,打破代码抽象风格的是他们在内存中存取object的方式. 在NSSet中, objects 是被强引用的(strongly referenced), 同样NSDictionary中的keys和values也会被NSDictionary复制。如果一个开发者想要存储一个weak类型的值或者使用一个没有实现NSCopying协议的object作为NSDictionary的key,他可能会很聪明的想到NSValue +valueWithNonretainedObject。 iOS6和OSX 10.5以后,可以分别使用和 NSSet, NSDictionary 地位相同的 NSHashTable,NSMapTable。
 
这两个类在Foundation的collection中不常用到,为了避免你慌乱无措,下面将介绍这两个类的用法。
 
NSHashTable
NSHashTable是更广泛意义的NSSet,区别于NSSet / NSMutableSet,NSHashTable有如下特性:
* NSSet / NSMutableSet是对其成员的强类型引用,这些成员被通过hash方法和isEqual方法来完成哈希和对比功能
* NSHashTable是可变的
* NSHashTable可以持有weak类型的成员变量
* NSHashTable可以在添加成员变量的时候复制成员
* NSHashTable可以随意的存储指针并且利用指针的唯一性来进行hash同一性检查(检查成员变量是否有重复)和对比操作(equal),用法如下:
  1. NSHashTable *hashTable = [NSHashTable hashTableWithOptions:NSPointerFunctionsCopyIn];
  2. [hashTable addObject:@"foo"];
  3. [hashTable addObject:@"bar"];
  4. [hashTable addObject:@42];
  5. [hashTable removeObject:@"bar"];
  6. NSLog(@"Members: %@", [hashTable allObjects]);
 
NSHashTable是根据一个option参数来进行初始化的,因为从OSX平台上移植到iOS平台上,原来OSX平台上使用的枚举类型被放弃了,从而用option来代替,命名也发生了一些变化:
 
NSHashTableStrongMemory: 等同于NSPointerFunctionsStrongMemory. 对成员变量进行强引用。这是一个默认值。如果采用这个默认值,NSHashTable和NSSet就没什么区别了。
 
NSHashTableWeakMemory: 等同于NSPointerFunctionsWeakMemory.对成员变量进行弱引用. 使用 NSPointerFunctionsWeakMemory, object 引用在最后释放的时候会被指向 NULL。
 
NSHashTableZeroingWeakMemory: 已被抛弃.使用NSHashTableWeakMemory 代替。
 
NSHashTableCopyIn: 在对象被加入集合之前进行复制 (NSPointerFunction -acquireFunction). 等同于NSPointerFunctionsCopyIn。
 
NSHashTableObjectPointerPersonality: 用指针来等同代替实际的值,当打印这个指针的时候相当于调用description方法。和NSPointerFunctionsObjectPointerPersonality等同。
 
NSMapTable
NSMapTable是对更广泛意义的NSDictionary。和NSDictionary / NSMutableDictionary相比具有如下特性:
* NSDictionary / NSMutableDictionary会复制keys并且通过强引用values来实现存储。
* NSMapTable是可变的。
* NSMapTable可以通过弱引用来持有keys和values,所以当key或者value被deallocated的时候,所存储的实体也会被移除。
* NSMapTable可以在添加value的时候对value进行复制
 
和NSHashTable类似,NSMapTable可以随意的存储指针,并且利用指针的唯一性来进行对比和重复检查。
 
用法:假设用NSMapTable来存储不用被复制的keys和被若引用的value,这里的value就是某个delegate或者一种弱类型。
  1. id delegate = ...;
  2. NSMapTable *mapTable = [NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory
  3. valueOptions:NSMapTableWeakMemory];
  4. [mapTable setObject:delegate forKey:@"foo"];
  5. NSLog(@"Keys: %@", [[mapTable keyEnumerator] allObjects]);
  6. 和NSHashTable类似,NSMapTable 也是根据一个option来初始化的。
  7. NSMapTableStrongMemory
  8. NSMapTableWeakMemory
  9. NSHashTableZeroingWeakMemory
  10. NSMapTableCopyIn
  11. NSMapTableObjectPointerPersonality
  12. Subscripting
  
看完上面几个小例子后,你可能会想 “为什么不使用object subscripting呢?”。一些激进的NSHipster估计已经开始动手写NSMapTable的subscripting category了。
 
那么为什么NSMapTable不能继承subscripting?
 
来看看下面的代码:
  1. - (id)objectForKeyedSubscript:(id <NSCopying>)key;
  2. - (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key;
 
注意:参数key是类型的。这对NSDictionary NSMutableDictionary来讲是非常有用的,但是我们不能臆断对NSMapTable也同样适用。我们陷入一个僵局:通过id ,我们不能利用NSMapTable实现subscripting。如果object subscripting 的代理方法放弃了 约束,那么使用NSMutableDictionary -setObject:forKeyedSubscript:的时候编译将得不到想要的结果。
 
所以说实话,对比NSMapTable所处的位置,句法的方便和快捷并不是大数人所关注的。
 
通常,记住编程不是为了让人更聪明,而是最大化抽象一个问题的能力。 NSSet and NSDictionary是非常伟大的类,他们能解决99%的问题,也无疑是用来工作的正确工具。如果,然而你的问题牵扯到上述的内存问题时候, NSHashTable 和 NSMapTable 是值得一看的。

【转】NSHashtable and NSMaptable的更多相关文章

  1. NSHashtable and NSMaptable

    本文转自Nidom的博客,原文:<NSHashtable & NSMaptable>   NSSet, NSDictionary, NSArray是Foundation框架关于集合 ...

  2. NSHashTable 和 NSMapTable学习

    今天,在实现play gif时间功能,我看见两个陌生班,只需看看这个纪录: NSSet和NSDictionary是两个经常使用的类,可是他们默认假定了当中对象的内存行为.对于NSSet.object是 ...

  3. NSDictionary和NSMaptable, NSArray,NSSet,NSOrderedSet和NSHashTable的区别

    NSSet, NSDictionary, NSArray是Foundation框架关于集合操作的常用类, 和其他标准的集合操作库不同, 他们的实现方法对开发者进行隐藏, 只允许开发者写一些简单的代码, ...

  4. NSHashTable NSPointerArray

    NSHashTable和NSMapTable能够对持有的对象做strong或weak存储,弱持有weak引用对象,当weak对象释放后会自动从表中移除     http://blog.csdn.net ...

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

    NSMapTable 不只是一个能放weak指针的 NSDictionary NSMapTable是早在Mac OS X 10.5(Leopard)的引入集合类.乍一看,这似乎是作为一个替换NSDic ...

  6. [转][iOS]NSHash​Table & NSMap​Table

    NSSet and NSDictionary, along with NSArray are the workhorse collection classes of Foundation. Unlik ...

  7. [iOS翻译]《iOS 7 Programming Pushing the Limits》系列:你可能不知道的Objective-C技巧

    简介: 如果你阅读这本书,你可能已经牢牢掌握iOS开发的基础,但这里有一些小特点和实践是许多开发者并不熟悉的,甚至有数年经验的开发者也是.在这一章里,你会学到一些很重要的开发技巧,但这仍远远不够,你还 ...

  8. 想进大厂嘛?这里有一份通关秘籍:iOS大厂面试宝典

    1.NSArray与NSSet的区别? NSArray内存中存储地址连续,而NSSet不连续 NSSet效率高,内部使用hash查找:NSArray查找需要遍历 NSSet通过anyObject访问元 ...

  9. ios NSHashTable & NSMapTable

    在ios开发中大家用到更多的集合类可能是像NSSet或者NSDictionary,NSArray这样的.这里要介绍的是更少人使用的两个类,一个是NSMapTable,另一个是NSHashTable. ...

随机推荐

  1. 商务智能(BI)技术

    以下内容仅为兴趣爱好. 商务智能技术是将数据仓库.联机分析处理(OLAP)和数据挖掘等结合起来应用到商业活动中,从不同的数据源收集数据,经过抽取(Extract).转换(Transform)和加载(L ...

  2. iOS8中添加的extensions总结(四)——Action扩展

    Action扩展 注:此教程来源于http://www.raywenderlich.com的<iOS8 by Tutorials> 1.准备 本次教程利用网站bitly.com进行 bit ...

  3. smarty 自定义函数

    自定义函数:<{方法名称}> 在lib/plugins中新建文件,命名方式是固定的:function.方法名称.php 或者 block.方法名称.php 1.<{literal}& ...

  4. PHPCMS v9构建模块

    ■补课: 1.phpcms v9帮助文件,上面会写关于二次开发的一些方法. http://v9.help.phpcms.cn/ 2.找一个后台还没安装的模块,先把代码看一边.比如dianping模块 ...

  5. C盘hosts

    # Copyright (c) - Microsoft Corp. # # This is a sample HOSTS file used by Microsoft TCP/IP for Windo ...

  6. Properties配置文件

    package file; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; ...

  7. Jasper_table_Cloud not resolve style(s)

    resolve method : delete style="".

  8. oldboy第四天学习

    一.感觉上课没有太多的知识.也可以去理解.但是作业太难了... 二.hash() #python里面的哈希类型是在一个程序中不变,如果换了python 哈希是不#一样的. #字典为什么快,因为他把字典 ...

  9. Android 解决服务端验证码问题

    服务端验证码解决方法. 在服务端生成验证码后会把验证码字符串存在服务端的session中,等待用户提交进行比对.为了保证服务器与客户端的一对一的关系,所以出现了session 和cookie技术.客户 ...

  10. css之marquee,让你的文字跳起来

    当你看到别人的网页文字动态效果美美哒,而你却为不会使用js而遗憾时,不妨看看这篇文章,教你如何只用css即可实现漂亮的文字滑动效果. 1.问题提出: 在一个特定大小的div中,如何让p标签内的内容动态 ...