字典
OC中字典是一个类似与数组的容器
保存的是一个个 键值对
所谓键值对 就是 一个key(键)对应一个value(值) 两者合成一个键值对
字典保存的内容是无序的, 不能像数组一样通过下标取出元素
字典存取元素需要通过唯一标识的key, 通过key获得对应的值.
存元素的的时候也需要给定一个唯一标识的key
- 元素和值 都必须是对象
- key作为键值, 具有唯一性, 在开发中一般使用字符串作为key值
value保存的是对象, 可以是一个字符串对象, 可以是一个类对象, 也可以是一个数组, 还可以是一个字典.
这样就可以完成一个非常复杂的数据结构.
比如字典的value保存的是数组, 数组里的对象是字典, 字典里再保存数组. 这样不断嵌套. 理论上只要内存空间足够大, 可以有无数种嵌套形式.
1.不可变字典NSDictionary
- 特点:
- 字典⼀旦创建,键值对就不可更改,不可添加,不可删除。
- 仅能读取key或者value。
1. 常用方法
- (id)objectForKey:(id)aKey; // 通过key获取key对应的对象
@property (readonly, copy) NSArray *allKeys; // 获得所有key 通常与forin循环连用
@property (readonly, copy) NSArray *allValues; // 获得所有values
2.便利构造器方法
+ (instancetype)dictionary; // 无参数的初始化方法
+ (instancetype)dictionaryWithObjectsAndKeys:(id)firstObject, ... NS_REQUIRES_NIL_TERMINATION; // 带不定个数参数的初始化方法
// 注: 本方法的弊端是必须先添加一个value再添加一个key, 每添加两个对象是一个键值对 常常会导致记不清当前哪个是value哪个是key
// 本方法常用
+ (instancetype)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
从网络和本地获取数据方法, 保存结果在字典中
+ (NSDictionary *)dictionaryWithContentsOfFile:(NSString *)path;
+ (NSDictionary *)dictionaryWithContentsOfURL:(NSURL *)url;
利用两个数组给字典初始化
NSArray *keys = @[@"name", @"sex", @"age"];
NSArray *values = @[@"赵日天", @"男性", @"18岁"];
NSDictionary *dic = [NSDictionary dictionaryWithObjects:values forKeys:keys];
NSLog(@"%@", dic);
字典初始化 语法糖方法
NSDictionary *dic = @{@"name":@"赵日天", @"age":@"18岁", @"sex":@"男"};
NSArray *keys = [dic allKeys];
NSArray *values = [dic allValues];
NSLog(@"%@\n%@", keys, values);
- 比较容易混淆的是 用语法糖时是先写key, 再写value. 而dictionaryWithObjectsAndKeys初始化方法是先写value再写key
接以上代码:
用objectForKey方法取值.
NSString *value = [dic objectForKey:@"name”]; // 因为键 name 对应的值是 字符串对象. 所以用一个字符串对象接收
NSLog(@"%@", value);
也可以写成
NSString *value = dic[@"name”]; // 类似于数组利用下标取值的方法. 写法上较为方便, 比较常用
NSLog(@"%@", value);
值得注意的是, 字典的count保存的是键值对的对数. 比如以上代码中
[dic count]
的值为3 而不是6
可变字典 NSMutableDictionary
常用方法
- 删除键值对的方法
- (void)removeObjectForKey:(id)aKey;
- 删除所有键值对的方法
- (void)removeAllObjects;
- 添加键值对的方法
- (void)setObject:(id)anObject forKey:(id <NSCopying>)aKey;
注意, 若是新添加的键值对, key是已添加过的key, 则新添加的键值对会覆盖之前key相同的键值对
常用的初始化方法
+ (instancetype)dictionary;
和
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
用法为:
NSMutableDictionary *dic1 = [NSMutableDictionary dictionary];
NSMutableDictionary *dic2 = [NSMutableDictionary dictionaryWithCapacity:10]; // 容量初始化大小随意, 因为可变数组超出后会自动扩充容量, 多出会自动回收
快速遍历(快速枚举): forin 语句
语句定义如下:
for (<#type *object#> in <#collection#>) {
<#statements#>
}
代码解释:
- type *object 对象名. 类型为容器中存放的对象类型.
- collection 为需要遍历的容器: (数组或字典等)
- <#type *object#> in <#collection#>表示判断对象是否在需要遍历的容器中, 若是则自动便遍历, 否则不执行大括号里的语句
- <#type *object#> 在花括号中的语句执行结束后会重新定义并赋值, 寻找下一个容器里的同类型对象 直到所有同类型对象都被遍历过一次
- <#statements#>表示判断成功后执行的语句
值得注意的一点是, <#type *object#> 定义的对象的值在执行语句中可以被赋值于其他对象, 可以被输出, 但是不能被改变
另外, 用forin语句遍历字典的时候, 打印的是字典的key如:
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
// ...
// ...
// 给字典赋值语句省略.
// ...
// ...
for (NSString *str in dic) {
NSLog(@"%@", str);
}
打印出来的结果是字典dic的key
集合
特点: 无序不重复
应用场景: 比如用来储存手机屏幕的像素点.
不可变集合NSSet
常用方法
- (id)anyObject;
返回一个计算机认为最合理的元素
常用的初始化方法:
+ (instancetype)set;
+ (instancetype)setWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
+ (instancetype)setWithArray:(NSArray *)array;
初始化集合代码如下:
NSSet *set = [[NSSet alloc] initWithObjects:@"1", @"2", @"3", @"2", @"2", @"2", nil];
NSLog(@"%@", set);
NSLog(@"%lu", [set count]);
由于集合是无序且不重复的,所以这里的count等于3 且打印set结果只有@“1”, @“2”, @“3”3个元素, 多余的@“2”不打印
获取集合中的一个元素
NSString *str = [set anObject];
NSLog(@"%@", str);
结果发现取出的永远是3, 这是计算机通过计算以后 返回的一个最合理的元素.
接集合的应用场景继续解释, 比如此时点击屏幕, 计算机会自动计算出最合理的一个元素, 既是我们点击的那个像素点, 返回.
可变集合NSMutableSet
- (void)addObject:(id)object; // 添加对象
- (void)removeObject:(id)object; // 删除对象
NSCountedSet
- 初始化方法
- (instancetype)initWithSet:(NSSet *)set;
注意, 若是从NSSet 或者 NSMutableSet作为数据源的时候, 无论NSSet 或NSMutableSet中是否有重复元素.最后保存在NSCountedSet对象中都不存在重复元素.
- (instancetype)initWithArray:(NSArray *)array;
把数组当作数据源的时候, 是会有重复元素的.
- 常用方法
- (NSUInteger)countForObject:(id)object;
计算某一元素重复出现的次数
数组排序
不可变数组的排序
- (NSArray *)sortedArrayUsingSelector:(SEL)comparator;
NSArray *array = @[@"1", @"3", @"5", @"4", @"2"];
NSArray * array2 = [array sortedArrayUsingSelector:@selector(compare:)];
NSLog(@"%@", array2);
缺陷是一次只比字符串的一个字符, 当比较的是保存不同位的数字的字符串时, 结果往往是错的, 且结果是升序的. 这里的排序结果是 1 2 3 4 5
可变数组的排序方法:
- (void)sortUsingSelector:(SEL)comparator;
NSMutableArray *array = [NSMutableArray arrayWithObjects:@"1", @"7", @"15", @"9", @"2", nil];
[array sortUsingSelector:@selector(compare:)];
NSLog(@"%@", array);
结果和不可变数组的排序缺陷相同. 这里的排序结果是:
1 15 2 7 9