[转][iOS]NSHashTable & NSMapTable
NSSet and NSDictionary, along with NSArray are the workhorse collection classes of Foundation. Unlike other standard libraries, implementation details are hidden from developers, allowing them to write simple code and trust that it will be (reasonably) performant.
However, even the best abstractions break down; their underlying assumptions overturned. In these cases, developers either venture further down the abstraction, or, if available use a more general-purpose solution.
For NSSet and NSDictionary, the breaking assumption was in the memory behavior when storing objects in the collection. For NSSet, objects are a strongly referenced, as are NSDictionary values. Keys, on the other hand, are copied by NSDictionary. If a developer wanted to store a weak value, or use a non-<NSCopying>-conforming object as a key, they could be clever and use NSValue +valueWithNonretainedObject. Or, as of iOS 6 (and as far back as OS X Leopard), they could use NSHashTable or NSMapTable, the more general-case counterparts to NSSet or NSDictionary, respectively.
So without further ado, here's everything you need to know about two of the more obscure members of Foundation's collection classes:
NSHashTable
NSHashTable is a general-purpose analogue of NSSet. Contrasted with the behavior of NSSet / NSMutableSet, NSHashTable has the following characteristics:
NSSet/NSMutableSetholdsstrongreferences to members, which are tested for hashing and equality using the methodshashandisEqual:.NSHashTableis mutable, without an immutable counterpart.NSHashTablecan holdweakreferences to its members.NSHashTablecancopymembers on input.NSHashTablecan contain arbitrary pointers, and use pointer identity for equality and hashing checks.
Usage
NSHashTable *hashTable = [NSHashTable hashTableWithOptions:NSPointerFunctionsCopyIn];
[hashTable addObject:@"foo"];
[hashTable addObject:@"bar"];
[hashTable addObject:@42];
[hashTable removeObject:@"bar"];
NSLog(@"Members: %@", [hashTable allObjects]);
NSHashTable objects are initialized with an option for any of the following behaviors. Deprecated enum values are due to NSHashTable being ported from Garbage-Collected OS X to ARC-ified iOS. Other values are aliased to options defined by NSPointerFunctions, which will be covered next week on NSHipster.
NSHashTableStrongMemory: Equal toNSPointerFunctionsStrongMemory. This is the default behavior, equivalent toNSSetmember storage.NSHashTableWeakMemory: Equal toNSPointerFunctionsWeakMemory. Uses weak read and write barriers. UsingNSPointerFunctionsWeakMemory, object references will turn toNULLon last release.NSHashTableZeroingWeakMemory: This option has been deprecated. Instead use theNSHashTableWeakMemoryoption.NSHashTableCopyIn: Use the memory acquire function to allocate and copy items on input (seeNSPointerFunction -acquireFunction). Equal toNSPointerFunctionsCopyIn.NSHashTableObjectPointerPersonality: Use shifted pointer for the hash value and direct comparison to determine equality; use the description method for a description. Equal toNSPointerFunctionsObjectPointerPersonality.
NSMapTable
NSMapTable is a general-purpose analogue of NSDictionary. Contrasted with the behavior of NSDictionary / NSMutableDictionary, NSMapTable has the following characteristics:
NSDictionary/NSMutableDictionarycopies keys, and holds strong references to values.NSMapTableis mutable, without an immutable counterpart.NSMapTablecan hold keys and values withweakreferences, in such a way that entries are removed when either the key or value is deallocated.NSMapTablecancopyits values on input.NSMapTablecan contain arbitrary pointers, and use pointer identity for equality and hashing checks.
Usage
Instances where one might use NSMapTable include non-copyable keys and storing weak references to keyed delegates or another kind of weak object.
id delegate = ...;
NSMapTable *mapTable = [NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory
valueOptions:NSMapTableWeakMemory];
[mapTable setObject:delegate forKey:@"foo"];
NSLog(@"Keys: %@", [[mapTable keyEnumerator] allObjects]);
NSMapTable objects are initialized with options specifying behavior for both keys and values, using the following enum values:
NSMapTableStrongMemory: Specifies a strong reference from the map table to its contents.NSMapTableWeakMemory: Uses weak read and write barriers appropriate for ARC or GC. UsingNSPointerFunctionsWeakMemory, object references will turn toNULLon last release. Equal toNSMapTableZeroingWeakMemory.NSHashTableZeroingWeakMemory: This option has been superseded by theNSMapTableWeakMemoryoption.NSMapTableCopyIn: Use the memory acquire function to allocate and copy items on input (see acquireFunction (seeNSPointerFunction -acquireFunction). Equal to NSPointerFunctionsCopyIn.NSMapTableObjectPointerPersonality: Use shifted pointer hash and direct equality, object description. Equal toNSPointerFunctionsObjectPointerPersonality.
Subscripting
NSMapTable doesn't implement object subscripting, but it can be trivially added in a category. NSDictionary's NSCopying requirement for keys belongs to NSDictionary alone:
@implementation NSMapTable (NSHipsterSubscripting)
- (id)objectForKeyedSubscript:(id)key
{
return [self objectForKey:key];
}
- (void)setObject:(id)obj forKeyedSubscript:(id)key
{
[self setObject:obj forKey:key];
}
@end
As always, it's important to remember that programming is not about being clever: always approach a problem from the highest viable level of abstraction. NSSet and NSDictionary are great classes. For 99% of problems, they are undoubtedly the correct tool for the job. If, however, your problem has any of the particular memory management constraints described above, then NSHashTable & NSMapTablemay be worth a look.
---------
作为delegate弱引用的集合再合适不过了。
[转][iOS]NSHashTable & NSMapTable的更多相关文章
- mysqldump:Couldn't execute 'show create table `tablename`': Table tablename' doesn't exist (1146)
遇到了一个错误mysqldump: Couldn't execute 'show create table `CONCURRENCY_ERRORS`': Table INVOICE_OLD.CONCU ...
- ORA-01747: user.table.column, table.column 或列说明无效
Oracle.DataAccess.Client.OracleException ORA-01747: user.table.column, table.column 或列说明无效 原因1: 查了一下 ...
- SQLServer temporary table and table variable
Temporary tables are created in tempdb. The name "temporary" is slightly misleading, for ...
- Oracle10g 回收站及彻底删除table : drop table xx purge
drop后的表被放在回收站(user_recyclebin)里,而不是直接删除掉.这样,回收站里的表信息就可以被恢复,或彻底清除. 1.通过查询回收站user_recyclebin获取被删除的表信息, ...
- user.table.column, table.column 或列说明无效
Oracle统计采用别名出错(user.table.column, table.column 或列说明无效) >>>>>>>>>>>& ...
- lua中打印所以类型功能实现table嵌套table
lua中打印所以类型功能实现 本人測试 number.string.bool.nil.table嵌套table.userdata没问题 共享一下有什么问题请拍砖 代码例如以下 cclog = func ...
- 使用vue的v-for生成table , 给table加上序号
现在有一个使用mybatis的分页插件生成的table,table中数据是通过vue获得的 , 前台显示使用<tr v-for="item in items"> 后台v ...
- 表优化 altering table OPTIMIZE TABLE `sta_addr_copy`
表优化 altering table OPTIMIZE TABLE `sta_addr_copy` [总结] 1.实际测试的结果是,在state sqlaltering table OPTIMIZE ...
- MySQL check table/optimize table/analyze table/REPAIR TABLE
MySQL check table/optimize table/analyze table/REPAIR TABLE 转自:https://www.cnblogs.com/datastack/p/3 ...
随机推荐
- 使用 Swagger 自动生成 ASP.NET Core Web API 的文档、在线帮助测试文档(ASP.NET Core Web API 自动生成文档)
对于开发人员来说,构建一个消费应用程序时去了解各种各样的 API 是一个巨大的挑战.在你的 Web API 项目中使用 Swagger 的 .NET Core 封装 Swashbuckle 可以帮助你 ...
- 苹果手机Safari无痕浏览模式下系统登录成功但是页面不跳转
昨天下午,测试提了一个bug,问题是:在苹果手机Safari无痕浏览模式下系统登录成功但是页面不跳转. 思前想后找了半天没思路,后来经过同事的点拨,说可能是禁用了cookie之类的,反正我也没思路就顺 ...
- 扎克伯格开发的家用AI: Jarvis
扎克伯格本周二在facebook发布了一篇文章,介绍自己利用个人时间开发的一套在自己家里使用的AI系统,并将它命名为Jarvis,对!就是电影钢铁侠里的AI助手Jarvis. 文章并没有讲细节的技术c ...
- 【原】使用Bmob作为iOS后台开发心得——云端代码添加其他User的Relation关系
本文转载请注明出处 —— polobymulberry-博客园 问题描述 我在User表中增加了两个列,分别为“我关注的人”(Relation关系)和“我的粉丝”(Relation关系)当我关注某个人 ...
- jQuery -原生 如何互转
今天研究源码的时候发现,不需要用get() 也能进行原生转换,使用原生方法. 原生- jQuery对象 var obj=document.xxx $(obj).css(); 也可以直接 $(doc ...
- YYModel 源码解读(二)之NSObject+YYModel.h (5)
好了,之前的博文中详细的解释了一些辅助的类和辅助的函数,接下来就是使用它们来实现酷炫功能的时候,正所谓磨刀不误砍柴工啊 我们先把总的功能罗列出来 1. json转字典 + ( ...
- Linux同平台数据库整体物理迁移
Linux同平台数据库整体物理迁移 需求:A机器不再使用,要将A机器的Oracle迁移到B机器. 之前写过类似需求的文章:http://www.cnblogs.com/jyzhao/p/3968504 ...
- 匹夫细说C#:庖丁解牛聊委托,那些编译器藏的和U3D给的
0x00 前言 由于工作繁忙所以距离上一篇博客已经过去一个多月的时间了,因此决心这个周末无论如何也得写点东西出来,既是总结也是分享.那么本文主要的内容集中在了委托的使用以及内部结构(当然还有事件了,但 ...
- [Spring]04_最小化Spring XML配置
4.1 自动装配 Bean Spring 装配 bean 时,有时非常明确,就是需要将某个 bean 的引用装配给指定属性. 例如,若应用上下文中只有一个 javax.sql.DataSource 类 ...
- java netty socket库和自定义C#socket库利用protobuf进行通信完整实例
之前的文章讲述了socket通信的一些基本知识,已经本人自定义的C#版本的socket.和java netty 库的二次封装,但是没有真正的发表测试用例. 本文只是为了讲解利用protobuf 进行C ...