容器介绍
数组
NSArray、NSMutableArray 是有序的、连续的同一类型值的集合,可根据索引快速访问。
NSPointerArray 可以插入nil,元素支持弱引用关系,可以再在元素加入的时候copy,
字典
NSDictionary、NSMutableDictionary 无序的键值对集合,每个键是唯一的,同一个对象可以存储在不同的键中。
NSMapTable 支持弱引用关系、添加的时候key和value都可以copy。
集合
NSSet、NSMutableSet 确定性、互异性、无序性,可以快速判断出对象是否在集合中。具有很好的存储和查找性能。 NSSet判断元素相等的条件:
- 两个对象的hash相同
- 两个对象的isEqual方法返回YES。(isEqual默认实现就是比较地址是否相同)
NSHashTable 支持弱引用关系,可以再元素加入的时候copy这个元素。支持任意指针类型的元素。本身是可变的,不存在不可变类型。
创建和与初始化
不可变容器init
| 标题 | 类型 |
|---|---|
| init空容器时 | __NSXXX0 |
| init一个对象时 | __NSSingleObjectXXXI |
| init多个对象 | __NSXXXI |
| 初始化可变容器 | __NSXXXM |
copy
| 不可变容器 | 可变容器 | |
|---|---|---|
| copy | 指针相同内部对象相同 | 指针拷贝,内部对象相同 |
| mutableCopy | 指针拷贝,内部对象相同 | 指针拷贝,内部对象相同 |
| init:copyItems:(obj实现NSCopying协议) | 指针不同,内部对象拷贝 | 指针不同,内部对象拷贝。 |
指针拷贝,内部对象相同。
指针不同,内部对象拷贝。
集合操作的时间复杂度
通常情况下数组的插入,要先给数组扩容,之后插入位置后面的元素向后搬移,时间复杂度为o(n). 我们来看下NSArray插入删除的表现 详细可以参考:www.laoqingcai.com/ios-nsmutab…
上文提到NSMutableArray继承__NSArrayM 包含如下属性,是一个环形缓冲区的接口,可以通过此结构减少插入删除的时间复杂度
- list:缓冲区元素数组首地址指针
- offset:缓冲区首个元素的位置索引
- size:缓冲区总大小
- used:缓冲区实际使用量大小
头插
只需要插入到最后,修改offset和used
中间插入
会找到距离头尾最近的地方,搬移数据,修改offset和used,时间复杂度o(n/2)
字典查找的时间复杂度:
NSDictionary是使用哈希表实现key和value之间的映射关系和存储的,hash函数设计的好坏决定了数据的查找访问效率,数据再hash表中分布越均匀,效率越高。通常采用哈希+链表的数据结构,解决hash冲突的问题,因此查找的时间复杂度为o(1)+o(n)最好为o(1)最坏是o(n)