热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

iOS:NSMutableArray和NSDictionary、NSSet底层原理、NSCache、copy/mutableCopy

一、NSMutableArray底层原理普通c数组,就是一段能被方便读写的连续内存控件。使用一段线性内存空间的一个最明显的缺点是,在下标0处插入一个元

一、NSMutableArray底层原理

普通c数组,就是一段能被方便读写的连续内存控件。
使用一段线性内存空间的一个最明显的缺点是,在下标 0 处插入一个元素时,需要移动其它所有的元素,同样地,假如想要保持相同的内存指针作为首个元素的地址,移除第一个元素需要进行相同的动作

NSMutableArray本质是一个对象。它采用了环形缓冲区的结构。在两端插入和删除非常的快。插入头尾只是修改offset指针,如果插入数据到达阀值,一样需要扩容。

只有中间插入和删除时,才需要移动较少的内容


二、NSDictionary底层原理

NSDictionary其实就是一个散列表,
对key进行hash算法得到对应的index,在对index进行 & 运算得到具体的桶的位置。

所以对NSMutableDictionary扩容时,必须是2的倍数。例如原始长度是16,扩容后的长度是32,这样做是为了 & 运算的结果一致

static int indexFor(int h, int length) {return h & (length-1);}

var a = 21; // 10101// 00111
var b = a & 7; //长度是8,这里要减1print("b is \(b)")
// 扩容后,8变成16
b = a & 15; //01111
print("b is \(b)")//打印
b is 5
b is 5

可以发现,&运算的结果一致。

但是扩容需要满足两个条件:


  1. 当前数据存储的数量(即size())大小必须大于等于阈值
  2. 当前加入的数据是否发生了hash冲突。

由于上面这两个条件,所以存在下面这些情况


  1. 就是hashmap在存值的时候(默认大小为16,负载因子0.75,阈值12),可能达到最后存满16个值的时候,再存入第17个值才会发生扩容现象,因为前16个值,每个值在底层数组中分别占据一个位置,并没有发生hash碰撞。

  2. 当然也有可能存储更多值(超多16个值,最多可以存26个值)都还没有扩容。原理:前11个值全部hash碰撞,存到数组的同一个位置(这时元素个数小于阈值12,不会扩容),后面所有存入的15个值全部分散到数组剩下的15个位置(这时元素个数大于等于阈值,但是每次存入的元素并没有发生hash碰撞,所以不会扩容),前面11+15=26,所以在存入第27个值的时候才同时满足上面两个条件,这时候才会发生扩容现象。


三、NSSet

NSSet和NSMutableSet是无序的,但是它保证数据的唯一性。当插入相同的数据时,不会有任何效果。从内部实现来说是hash表,所以可以常数时间内查找一个数据。

常用函数:

[NSSet setWithSet:(NSSet *)set];
用另外一个set对象构造[NSSet setWithArray:(NSArray *)array];用数组构造[NSSet setWithObjects:...]:创建集合对象,并且初始化集合中的数值,结尾必需使用nil标志。[set count] ;得到这个结合对象的长度。[set containsObject:...]:判断这个集合中是否存在传入的对象,返回Bool值。[set objectEnumerator]:将集合放入迭代器。[enumerator nextObject]:得到迭代器中的下一个节点数据,使用while遍历这个迭代器,方可遍历集合对象中的对象。[set isEqualToSet:objset]:判断两个集合是否完全相等,返回Bool值。[set isSubsetOfSet:objset]:判断集合中的所有数据是否都相等与objeset集合中,返回Bool值。[set allObjects];

四、NSCache

NSCache 基本上就是一个会自动移除对象来释放内存的 NSMutableDictionary。无需响应内存警告或者使用计时器来清除缓存。唯一的不同之处是键对象不会像 NSMutableDictionary 中那样被复制

- (void)viewDidLoad {[super viewDidLoad];self.cache &#61; [[NSCache alloc] init];[self.cache setDelegate:self];self.cache.countLimit &#61; 40;for (int i &#61; 0; i < 50; i &#43;&#43;) {[self.cache setObject:&#64;(i) forKey:[NSString stringWithFormat:&#64;"key_%d",i]];}NSLog(&#64;"-|%&#64;",[self.cache objectForKey:&#64;"key_2"]);NSLog(&#64;"-|%&#64;",[self.cache objectForKey:&#64;"key_12"]);}
- (void)cache:(NSCache *)cache willEvictObject:(id)obj {NSLog(&#64;"---%&#64;",obj);
}// ----------
2020-09-16 16:14:15.779289&#43;0800 Test[40675:709451] ---0
2020-09-16 16:14:15.779461&#43;0800 Test[40675:709451] ---1
2020-09-16 16:14:15.779563&#43;0800 Test[40675:709451] ---2
2020-09-16 16:14:15.779648&#43;0800 Test[40675:709451] ---3
2020-09-16 16:14:15.779727&#43;0800 Test[40675:709451] ---4
2020-09-16 16:14:15.779803&#43;0800 Test[40675:709451] ---5
2020-09-16 16:14:15.779873&#43;0800 Test[40675:709451] ---6
2020-09-16 16:14:15.779935&#43;0800 Test[40675:709451] ---7
2020-09-16 16:14:15.780014&#43;0800 Test[40675:709451] ---8
2020-09-16 16:14:15.780199&#43;0800 Test[40675:709451] ---9
2020-09-16 16:14:15.780408&#43;0800 Test[40675:709451] -|(null)
2020-09-16 16:14:15.780667&#43;0800 Test[40675:709451] -|12

NSCache提供了可设置缓存的数目与内存大小限制的方式。保证了处理的数据的线程安全性。缓存使用的key不需要是实现NSCopying的类。


当内存警告时内部自动清理部分缓存数据。
进入后台也会清理内存



五、copy/mutableCopy

这几个容器类的对象&#xff0c;不管是copy还是mutableCopy&#xff0c;都不会拷贝里面的对象&#xff0c;如果想要拷贝里面的对象&#xff0c;使用如下函数

- (instancetype)initWithDictionary:(NSDictionary<KeyType, ObjectType> *)otherDictionary copyItems:(BOOL)flag;- (instancetype)initWithSet:(NSSet<ObjectType> *)set copyItems:(BOOL)flag;- (instancetype)initWithArray:(NSArray<ObjectType> *)array copyItems:(BOOL)flag;

推荐阅读
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • Python爬虫中使用正则表达式的方法和注意事项
    本文介绍了在Python爬虫中使用正则表达式的方法和注意事项。首先解释了爬虫的四个主要步骤,并强调了正则表达式在数据处理中的重要性。然后详细介绍了正则表达式的概念和用法,包括检索、替换和过滤文本的功能。同时提到了re模块是Python内置的用于处理正则表达式的模块,并给出了使用正则表达式时需要注意的特殊字符转义和原始字符串的用法。通过本文的学习,读者可以掌握在Python爬虫中使用正则表达式的技巧和方法。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
author-avatar
981378224_014f95
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有