NSDictionary:字典,是一种以Key:Value的形式存储数据的形式。简单来说就是使用一个标识字符串来标志一个值。在使用的时候,我们就可以直接使用标识。可以理解为一堆变量的集合。既然是集合,那么就有集合的无序性。这个和数组不同。

键(key):可以为任何对象(但通常都是NSString类型的字符串),必须是单值。

值(value):可以是任何对象,不能是nil。

对于字典的使用,通常是使用键来读取查询相对应的值。

创建一个字典对象的方法有很多,在官方的NSDictionary类中有一下方法可以用来创建一个字典对象:

+ (instancetype)dictionary;

+ (instancetype)dictionaryWithObject:(ObjectType)object forKey:(KeyType <NSCopying>)key;

#if TARGET_OS_WIN32

+ (instancetype)dictionaryWithObjects:(const ObjectType [])objects forKeys:(const KeyType [])keys count:(NSUInteger)cnt;

#else

+ (instancetype)dictionaryWithObjects:(const ObjectType [])objects forKeys:(const KeyType <NSCopying> [])keys count:(NSUInteger)cnt;

#endif

+ (instancetype)dictionaryWithObjectsAndKeys:(id)firstObject, ... NS_REQUIRES_NIL_TERMINATION NS_SWIFT_UNAVAILABLE("Use dictionary literals instead");

+ (instancetype)dictionaryWithDictionary:(NSDictionary<KeyType, ObjectType> *)dict;

+ (instancetype)dictionaryWithObjects:(NSArray<ObjectType> *)objects forKeys:(NSArray<KeyType <NSCopying>> *)keys;

- (instancetype)initWithObjectsAndKeys:(id)firstObject, ... NS_REQUIRES_NIL_TERMINATION;

- (instancetype)initWithDictionary:(NSDictionary<KeyType, ObjectType> *)otherDictionary;

- (instancetype)initWithDictionary:(NSDictionary<KeyType, ObjectType> *)otherDictionary copyItems:(BOOL)flag;

- (instancetype)initWithObjects:(NSArray<ObjectType> *)objects forKeys:(NSArray<KeyType <NSCopying>> *)keys;

+ (nullable NSDictionary<KeyType, ObjectType> *)dictionaryWithContentsOfFile:(NSString *)path;

+ (nullable NSDictionary<KeyType, ObjectType> *)dictionaryWithContentsOfURL:(NSURL *)url;

- (nullable NSDictionary<KeyType, ObjectType> *)initWithContentsOfFile:(NSString *)path;

- (nullable NSDictionary<KeyType, ObjectType> *)initWithContentsOfURL:(NSURL *)url;

在我们实际的使用中,常用的方法有:

创建一个字典对象

+ (instancetype)dictionary;

创建一个字典对象,并使用K:V形式初始化数据

+ (instancetype)dictionaryWithObject:(ObjectType)object forKey:(KeyType <NSCopying>)key;

创建一个字典对象,并使用另一个字典初始化数据

+ (instancetype)dictionaryWithDictionary:(NSDictionary<KeyType, ObjectType> *)dict;

创建一个字典对象,使用K数组和V数组初始化数据

+ (instancetype)dictionaryWithObjects:(NSArray<ObjectType> *)objects forKeys:(NSArray<KeyType <NSCopying>> *)keys;

创建一个字典对象,并使用K:V形式初始化数据

- (instancetype)initWithObjectsAndKeys:(id)firstObject, ... NS_REQUIRES_NIL_TERMINATION;

创建一个字典对象,并使用另一个字典初始化数据

- (instancetype)initWithDictionary:(NSDictionary<KeyType, ObjectType> *)otherDictionary;

上面的创建方法其实大体都是一样的。区别在于调用方式和初始化方式的不同。下面看看字典有哪些常用属性和方法

字典的常用属性和方法:

属性:

字典词条数量

@property (readonly) NSUInteger count;

字典中所有的键Key

@property (readonly, copy) NSArray<KeyType> *allKeys;

字典中所有的值Value

@property (readonly, copy) NSArray<ObjectType> *allValues;

字典内容描述的字符串,plist格式

@property (readonly, copy) NSString *description;

.string格式字典内容描述的字符串,

@property (readonly, copy) NSString *descriptionInStringsFileFormat;

代码示例:

//创建字典对象,初始化

NSDictionary *dic = [NSDictionary dictionaryWithObjects:@[@"jeck", @"20", @"boy"] forKeys:@[@"name", @"age", @"sex"]];

//打印字典条目数量(长度)

NSLog(@"字典条目数量:%lu", dic.count);

//打印字典所有的key

NSLog(@"字典所有的key:%@", dic.allKeys);

//打印字典所有的value

NSLog(@"字典所有的value:%@", dic.allValues);

//打印字典描述,plist格式

NSLog(@"plist格式描述:%@", dic.description);

//打印.string格式字典内容描述

NSLog(@".string格式字典内容描述:%@", dic.descriptionInStringsFileFormat);

打印结果:

2017-03-21 10:21:14.071 OCdemo[698:35153] 字典条目数量:3

2017-03-21 10:21:14.072 OCdemo[698:35153] 字典所有的key:(

    name,

    age,

    sex

)

2017-03-21 10:21:14.072 OCdemo[698:35153] 字典所有的value:(

    jeck,

    20,

    boy

)

2017-03-21 10:21:14.072 OCdemo[698:35153] plist格式描述:{

    age = 20;

    name = jeck;

    sex = boy;

}

2017-03-21 10:21:14.072 OCdemo[698:35153] .string格式字典内容描述:"name" = "jeck";

"age" = "20";

"sex" = "boy";

Program ended with exit code: 0

在上面的打印结果中, description和descriptionInStringsFileFormat的区别只是description是一个字典格式的数据输出,descriptionInStringsFileFormat是一个字符串格式的数据输出。

字典数据的读取

之所以会有字典这种数据形式,就是为了使用key去读取和查询value。既然如此,那么字典数据的读取就很简单了,就是使用字典的key就可以获取到value。

这就是读取字典中value的方法

- (nullable ObjectType)objectForKey:(KeyType)aKey;

代码示例:

NSDictionary *dic = [NSDictionary dictionaryWithObjects:@[@"jeck", @"20", @"boy"] forKeys:@[@"name", @"age", @"sex"]];

//读取字典中存储的姓名

NSString *nameString = [dic objectForKey:@"name"];

//打印读取结果

NSLog(@"姓名:%@", nameString);

打印结果:

2017-03-21 10:27:21.206 OCdemo[709:37052] 姓名:jeck

Program ended with exit code: 0

在上面的代码中,会有一个小问题,那就是当在取值的时候,objectForKey:方法后面传入的参数是一个字符串,这样的形式使得在开发中,可以根据自己或者团队统一定义命名方式存取数据,很便于管理。但是也有一些问题,那就是字符串在Xcode中是不会被检查报错的,即使我们写错了key,系统也不回给报出错误,所以,在这里一定要特别小心,不要出现一些这样的错误。

字典的常用操作

枚举遍历字典中的key或者value

返回一个可以快速访问字典中所有关键字(key)的快速枚举器。

- (NSEnumerator<KeyType> *)keyEnumerator;

返回一个可以快速访问字典中所有值(value)的快速枚举器。

- (NSEnumerator<ObjectType> *)objectEnumerator;

返回字典中所有值anObject对应的key。

- (NSArray<KeyType> *)allKeysForObject:(ObjectType)anObject;

代码示例:

//创建字典对象,初始化

NSDictionary *dic = [NSDictionary dictionaryWithObjects:@[@"jeck", @"20", @"boy"] forKeys:@[@"name", @"age", @"sex"]];

//创建关键字遍历枚举器

NSEnumerator *keyEnumera = [dic keyEnumerator];

//指向下一个对象

id key = [keyEnumera nextObject];

//遍历

while (key) {

NSLog(@"keyEnumera :%@", [dic objectForKey:key]);

key = [keyEnumera nextObject];

}

NSLog(@"---------------分割线--------------");

//创建值遍历枚举器

NSEnumerator *valueEnumer = [dic objectEnumerator];

//指向下一个对象

id value = [valueEnumer nextObject];

//遍历

while (value) {

NSLog(@"valueEnumer :%@", [dic allKeysForObject:value]);

value = [valueEnumer nextObject];

}

打印结果:

2017-03-21 10:48:29.190 OCdemo[794:45990] keyEnumera :jeck

2017-03-21 10:48:29.191 OCdemo[794:45990] keyEnumera :20

2017-03-21 10:48:29.192 OCdemo[794:45990] keyEnumera :boy

2017-03-21 10:48:29.192 OCdemo[794:45990] ---------------分割线--------------

2017-03-21 10:48:29.192 OCdemo[794:45990] valueEnumer :(

    name

)

2017-03-21 10:48:29.192 OCdemo[794:45990] valueEnumer :(

    age

)

2017-03-21 10:48:29.193 OCdemo[794:45990] valueEnumer :(

    sex

)

Program ended with exit code: 0

从上面的打印结果来看,使用key遍历打印的都是一个个字符串值,而使用value遍历打印的是一个个的数组,这是因为没有一个方法可以像objectForKey:一样很方便通过值去获取到key,所以这里算是‘作弊’的形式,使用 allKeysForObject:方法展示一下value对应的key。这里需要注意,当在这个字典里有多个key对应相同的值的时候,这样打印就不是这样了。看下面的代码:

NSDictionary *dic = [NSDictionary dictionaryWithObjects:@[@"jeck", @"20", @"boy", @"20"] forKeys:@[@"name", @"age", @"sex", @"number"]];

//创建值遍历枚举器

NSEnumerator *valueEnumer = [dic objectEnumerator];

//指向下一个对象

id value = [valueEnumer nextObject];

//遍历

while (value) {

NSLog(@"valueEnumer :%@", [dic allKeysForObject:value]);

value = [valueEnumer nextObject];

}

打印结果:

2017-03-21 10:53:59.131 OCdemo[834:48011] valueEnumer :(

    age,

    number

)

2017-03-21 10:53:59.132 OCdemo[834:48011] valueEnumer :(

    sex

)

2017-03-21 10:53:59.132 OCdemo[834:48011] valueEnumer :(

    age,

    number

)

2017-03-21 10:53:59.132 OCdemo[834:48011] valueEnumer :(

    name

)

Program ended with exit code: 0

看到结果的时候就会发现 objectEnumerator是遍历所有的value,而allKeysForObject:是获取所有的value对应的key,在上面的字典中,20 对应的key有name和number。所以才会这样额打印输出。

字典的比较

比较两个字典是否相同

- (BOOL)isEqualToDictionary:(NSDictionary<KeyType, ObjectType> *)otherDictionary;

代码示例:

NSDictionary *dic = [NSDictionary dictionaryWithObjects:@[@"jeck", @"20", @"boy", @"20"] forKeys:@[@"name", @"age", @"sex", @"number"]];

NSDictionary *dic1 = [NSDictionary dictionaryWithObjects:@[@"jeck", @"20", @"boy", @"20"] forKeys:@[@"name", @"age", @"sex", @"number"]];

//使用isEqualToDictionary:比较

if ([dic isEqualToDictionary:dic1]) {

NSLog(@"相同");

}else{

NSLog(@"不同");

}

//使用==比较

if (dic1 == dic) {

NSLog(@"相同");

}else{

NSLog(@"不同");

}

//打印地址

NSLog(@"dic的地址:%p,dic1的地址:%p", &dic, &dic1);

打印结果:

2017-03-21 11:01:30.400 OCdemo[876:50380] 相同

2017-03-21 11:01:30.401 OCdemo[876:50380] 不同

2017-03-21 11:01:30.401 OCdemo[876:50380] dic的地址:0x7fff5fbff770,dic1的地址:0x7fff5fbff768

Program ended with exit code: 0

从上面的打印结果可以看出,isEqualToDictionary:方法比较的是两个字典的key和value是否完全相同,因为字典的无序性,即使顺序不同也只要对应的key:value相同,那么这两个字典也是相同的。而使用‘==’进行判断时不仅仅是key、value还有地址。==表示两个对象完全一样,地址不同就是两个对象,当然不可能完全一样。

字典遍历

上面已经说了枚举遍历字典的方法,下面再来说几个遍历字典的方法:

1、使用allValues方法获取字典中所有的值进行数组遍历

NSDictionary *dic = [NSDictionary dictionaryWithObjects:@[@"jeck", @"20", @"boy", @"20"] forKeys:@[@"name", @"age", @"sex", @"number"]];

//获取字典中所有的value

NSArray *valuesArray = [dic allValues];

//for循环遍历

for (int i = 0; i < valuesArray.count; i++) {

NSLog(@"%@", valuesArray[i]);

}

NSLog(@"--------------分割线------------");

//for-in循环遍历

for (NSDictionary *dic in valuesArray) {

NSLog(@"%@",dic);

}

打印结果:

2017-03-21 11:15:03.533 OCdemo[927:55325] 20

2017-03-21 11:15:03.534 OCdemo[927:55325] boy

2017-03-21 11:15:03.534 OCdemo[927:55325] 20

2017-03-21 11:15:03.534 OCdemo[927:55325] jeck

2017-03-21 11:15:03.534 OCdemo[927:55325] --------------分割线------------

2017-03-21 11:15:03.535 OCdemo[927:55325] 20

2017-03-21 11:15:03.535 OCdemo[927:55325] boy

2017-03-21 11:15:03.535 OCdemo[927:55325] 20

2017-03-21 11:15:03.535 OCdemo[927:55325] jeck

Program ended with exit code: 0

2、使用allKeys方法获取所有的key,再使用objectForKey:方法获取对应的value,进行循环遍历

NSDictionary *dic = [NSDictionary dictionaryWithObjects:@[@"jeck", @"20", @"boy", @"20"] forKeys:@[@"name", @"age", @"sex", @"number"]];

//获取字典中所有的key

NSArray *keysArray = [dic allKeys];

//for循环遍历

for (int i = 0; i < keysArray.count; i++) {

NSLog(@"%@", [dic objectForKey:keysArray[i]]);

}

NSLog(@"--------------分割线-------------");

//for-in循环遍历

for (NSString *keyString in keysArray) {

NSLog(@"%@", [dic objectForKey:keyString]);

}

打印结果:

2017-03-21 11:18:33.933 OCdemo[950:56650] 20

2017-03-21 11:18:33.934 OCdemo[950:56650] boy

2017-03-21 11:18:33.934 OCdemo[950:56650] 20

2017-03-21 11:18:33.934 OCdemo[950:56650] jeck

2017-03-21 11:18:33.934 OCdemo[950:56650] --------------分割线-------------

2017-03-21 11:18:33.934 OCdemo[950:56650] 20

2017-03-21 11:18:33.934 OCdemo[950:56650] boy

2017-03-21 11:18:33.934 OCdemo[950:56650] 20

2017-03-21 11:18:33.934 OCdemo[950:56650] jeck

Program ended with exit code: 0

前面说到字典是无序的,那么我们在遍历的时候,所得到的值也就是无序的,要想实现有序遍历该如何呢?

3、有序遍历

NSDictionary *dic = [NSDictionary dictionaryWithObjects:@[@"jeck", @"10", @"boy", @"20"] forKeys:@[@"name", @"age", @"sex", @"number"]];

//获取字典中所有的key

NSArray *keysArray = [dic allKeys];

//对key数组进行排序

keysArray = [keysArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2){

NSComparisonResult result = [obj1 compare:obj2];

return result==NSOrderedDescending;

}];

//for循环遍历

for (int i = 0; i < keysArray.count; i++) {

NSLog(@"%@", [dic objectForKey:keysArray[i]]);

}

NSLog(@"--------------分割线-------------");

//for-in循环遍历

for (NSString *keyString in keysArray) {

NSLog(@"%@", [dic objectForKey:keyString]);

}

打印结果:

2017-03-21 11:22:41.922 OCdemo[971:58569] 10

2017-03-21 11:22:41.923 OCdemo[971:58569] jeck

2017-03-21 11:22:41.924 OCdemo[971:58569] 20

2017-03-21 11:22:41.924 OCdemo[971:58569] boy

2017-03-21 11:22:41.924 OCdemo[971:58569] --------------分割线-------------

2017-03-21 11:22:41.924 OCdemo[971:58569] 10

2017-03-21 11:22:41.925 OCdemo[971:58569] jeck

2017-03-21 11:22:41.925 OCdemo[971:58569] 20

2017-03-21 11:22:41.925 OCdemo[971:58569] boy

Program ended with exit code: 0

打印来看,age对应的10最先被打印出来,因为在排序中age是被排带最前面。

到这里,不可变字典的一些常用操作就说完了。下一篇是可变字典(NSMutableDictionary)的操作,与字符串和数组一样,可变字典是继承自NSDictionary的,所以,这篇文章中说到的属性和方法都是适用的。

OC--NSDictionary字典相关推荐

  1. [Objective-C]OC中字典基本概念和常用方法(NSDictionary和NSMutableDictionary)

    一:字典的基本概念 Foundation中的字典(NSDictionary,NSMutableDictionary)是由键-值对组成的数据集合.正如,我们在字典里查找单词的定义一样. 通过key(键) ...

  2. iOS 开发 OC编程 字典和集合 排序方法

    // //  main.m //  oc- 05 字典和集合 // //  Created by dllo on 15/10/29. //  Copyright (c) 2015年 dllo. All ...

  3. Objective-C ,ios,iphone开发基础:NSDictionary(字典) 和 NSMutableDictionary

    NSDictionary(字典),NSDictionary类似于 .net中的parameter,l类似于java中的map. 通过唯一的key找到对应的值,一个key只能对应一个只,而多个key可以 ...

  4. NSDictionary - 字典

    /*------------------------------------创建字典------------------------------------*/ //- (id) initWithOb ...

  5. OC --(5)-- 字典、集、数组排序:字典类、集合类、数组数组排序、字典、集合的快速遍历、数组排序...

    字典 1.快速枚举 forin   运行时不能更改内部数据 for (<#type *object#> in <#collection#>) { <#statements ...

  6. iOS (swift,oc)字典转模型(一)框架 YYModel HandyJSON

    返回上级目录:IOS常用的第三方库(框架) 文章目录 1.纯swift框架 1.1-HandyJSON:`star:3.6k`据说是阿里巴巴的开源项目,第一眼我就相中了,打算用这个 1.1.1 jso ...

  7. OC中用字典创建一个具有省市区的应用(简单的字典运用代码)

    </pre><pre name="code" class="objc">#import <Foundation/Foundatio ...

  8. OC语言笔记(三):OC数组和字典

    提示: C和OC的差别 1.C的数组,只能存一种类型,OC的数组,可以同时保存不同类型的对象 2.C的数组,一般保存基本数据类型,OC的数组,只能保存对象 OC的数组 一.NSArray 1.实例化 ...

  9. Swift3的Dictionary和OC的NSDictionary关系

    在Foundation框架中提供一种字典集合,它是由"键-值"对构成的集合.键集合不能重复, 值集合没有特殊要求.键和值集合中的元素可以是任何对象,但是不能是nil.Foundat ...

  10. OC中NSDictionary常用方法总结

    //不可变字典NSDictionary //字典的创建 NSDictionary *dic1=[NSDictionary dictionaryWithObject:@"velue" ...

最新文章

  1. .NET笔试题集(五)
  2. Spring AOP与IOC以及自定义注解
  3. 05后都上清华了!首批丘成桐数学领军人才名单发布,三位菲尔兹奖得主为其授课,周末就来学校报到...
  4. pyinstaller打包教程及错误RuntimeError: Unable to open ./shape_predictor_68_face_landmarks.dat
  5. [置顶]       Mybatis技术(二) MyBatis-Spring
  6. android 8.0手机开服务端,Android 8.0 + Service开启方式兼容处理
  7. Leetcode1:Two Sum
  8. python图形代码怎么写_【Python3-API】定制化图像接口示例代码
  9. 解决Windows 10下MySQL 5.7中文乱码问题
  10. java编程基础码_1.java编程基础
  11. Galaxy Nexus(i9250)卡在开机画面(‘X’画面)解决方法
  12. 停止运行_部门动态丨供水运行不能中断,保障维修从未停止
  13. python扫描端口hack_一款集http端口扫描和目录批量扫描为一体的自动化工具
  14. 软件测试方法和技术有哪些?
  15. 38. Python批量翻译英语单词
  16. 一个前端所需具备的PS能力
  17. 计算机网络安全 的论文,网络安全论文3000字范文参考(3)
  18. element ui el-table单元格按需合并
  19. 魔法诗~~~一套基于Vue开发的实用、高端、炫酷的响应式前端网页!!!
  20. 完整数字华容道03:首页创建

热门文章

  1. 数字人民币持续推进,带来哪些利好?
  2. 【SCP命令】Linux和Windows下的文件互传
  3. “70”迈智能后视镜:你的专属出行骑士
  4. 一个屌丝程序猿的人生(三十七)
  5. 瓦罐香沸快餐 特色盈利项目
  6. 【图像分割】基于FCM和改进的模糊聚类FCM实现脑部CT图像分割matlab源码
  7. python循环10次怎么写_python循环怎么写
  8. 三种常用的直线裁剪算法
  9. ENSP 静态路由加VLANIF实例
  10. 浅谈GPU虚拟化技术(三)GPU SRIOV及vGPU调度