zoukankan      html  css  js  c++  java
  • NSDictionary and NSMutableDictionary

     

    0,铺垫

    做程序员早期,我对各种编程语言提供的、类似于“STL”这样的API有一种不信任感,总觉得那是把简单的事情搞复杂。

    后来维护了一个项目(2004年),该项目用C++编写,用了一些STL中的vector、iterator一类的东西,首次感受到用STL实现一些基础数据结构操作的便利性。

    但头脑中的不信任感并没有完全去除,在接下来的三年,由于主要使用C语言,所以依然用最底层代码自己写单、双向链表,哈希表,FIFO队列,长度自增数组。

    在一次项目升级前(2006年),关于是否用C++替换C引起了争论,当时我是Linux迷,所以坚定的站在Linus Tovard这边选择了C,最终C阵营获胜,原因是:1、无切换成本。2、效率稍高。于是又失去了一次拥抱变化的机会。

    这次做iOS下一个数据管理的软件处理数据缓存,既要有非常好快的单条记录访问速度,用来更新记录内容,又要能快速返回有序的子数据集。经过简单思考后,决定用NSDictionary来作为根容器缓存数据。没想到随着使用越来越深入,对它的了解越来越多,我发现已经渐渐爱上了它。。。

    废话扯完,讲讲NSDictionary的一些特性(以下不区别NSDictionary和NSMutableDictionary):

     

    1,NSDictionary使用Hash表实现Key/Object存储。

    Hash表是一种访问速度很快的数据结构,前提是Hash函数设计合理,能够使数据在各个子节点均匀分布,这一点使用NSString对象可以保证,这是文档中的说明:

         Classes such as NSString that are part of Foundation have a good hash function.

     

    2,NSDictionary对于Key和Object的处理方式不同。

    setObject:(id)object forKey:(id)key 是NSDictionary常用的message接口,第一个参数是你要存储的对象,第二个参数用来生成Hash入口(一般用NSString对象)。

    key必须遵从NSCopying协议,在调用时,NSDictionary会在内部创建一个具有相同内容的内存对象,并不会引用key。

    object对象却不然,NSDictionary在内部对它进行了强引用(想想ARC中的strong),也就意味着两个指针指向同一个地址,所以你可以写这样的代码:

         NSMutableDictionary * dict = [[NSMutableDictionary alloc] init];

         NSMutableArray * array = [[NSMutableArray alloc] init];

         [dict setObject:array forKey:@"kArrayValue"];

         [array addObject:@"FirstObject"];                                   

    将array插入到dict后,继续修改array的内容,相当于修改dict中存储的内容。

     

    3,除了NSString,还能使用其它类型的对象作为key吗?

    可以,但必须继承自NSObject,并且必须重载hash和isEqual:两个消息处理接口。

    hash:计算该对象的hash值,用来定位Hash表入口。所以请写一个分布均匀的hash函数。

    isEqual:通过hash值定位的Hash表入口可能有多个具有相同hash值的对象,所以在访问数据时要通过这个函数来找到相等的对象。

     

    4,简单后记。

    除了以上三点以外,我还曾为一个问题纠结过,看下面的情况:

         NSString * key1 = @"123";

         int a = 123;

         NSString * key2 = [NSString stringWithFormat:@"%d”, a];

    key1和key2有相同的内容(都是“123”),但他们是不同的对象,所以他们的hash值相同吗?如果不同就麻烦了。

    好在他们的hash值是一样的,因为在NSString的文档中,搜索“hash”,你可以看到下面的话:

         If two string objects are equal (as determined by the isEqualToString: method), they must have the same hash value.

         The abstract implementation of this method fulfills this requirement, so subclasses of NSString shouldn’t override it. 

    所以使用一些高级数据结构,并非一定会降低效率,但肯定会提高代码的健壮性,前提是按照要求合理的使用它。回想那些年写“单、双向链表,哈希表,FIFO队列,长度自增数组”的岁月,泪流满面。

  • 相关阅读:
    移动端开发必须知道的小技巧
    前端程序员被聘用的13个开发技能
    AIOps产品与架构浅析【华为云技术分享】
    su和sudo的区别与使用【华为云技术分享】
    为什么我不喜欢数据库三范式【华为云技术分享】
    python推导式pythonic必备【华为云技术分享】
    理解递归与动态规划【华为云技术分享】
    Spring Boot 最流行的 16 条实践解读!【华为云技术分享】
    机器学习笔记(六) ---- 支持向量机(SVM)【华为云技术分享】
    独立物理机和虚拟机比较有什么优势?【华为云技术分享】
  • 原文地址:https://www.cnblogs.com/tara/p/2953602.html
Copyright © 2011-2022 走看看