古老的C数组:

优点:查询速度很快,直接通过下表找到对应的值
缺点:修改、删除数据很慢,需要移动基于所有的其他的元素
 
插入和删除一个元素,需要移动后面所有的元素
改进的目标:实现快速增加,删除

NSMutableArray的内部数据结构如下:

几个主要变量:
offset: 有效数据起始位置偏移量
size: 实际占用的内存大小
used: 数组的实际的有效数据个数
*list: 实际内存的起始地址
 

删除元素

[arr removeObjecAtIndex:0];
[arr removeObjecAtIndex:0];

 

执行两次 remove的实现:
仅仅修改 offset即可,内存完全不需要移动。
那么问题来了,移走的这个元素的内存怎么释放的呢?
回到OBJC的引用计数,offset移走,这个对象的引用计数减一,对象引用计数到0之后,由autoreleasepool释放。over

插入元素

[arr insertObjec:@"test"atIndex:0];

 

执行insertObjec的实现:
 
 
如果buff的size还够用,不需要扩展buff,数据会在buff的末端添加进去,此时offset由0变成size-1,used+1.over
循环buff的牛逼之处就在于此,无需移动内存,实现插入元素。

删除元素

[arr removeObjecAtIndex:3];

 

实现:
 
 
删除头尾元素直接修改offset或者used即可
但是如果删除中间元素,就避免不了移动其他元素,不过NSArray会选择更少移动的那一边移动数据。
所以我们在实际使用过程中应该尽量避免这么做。

tip:

NSMutableArray *array = [NSMutableArray array];
 
for (int i = 0; i < 10000; i++) {
    [array addObject:[NSObject new]];
}
[array removeAllObjects];
 
数组移除所有元素,buff并不会被立即清空
输出size的结果:
1
Size: 14336 
如果你在利用NSArray保存大量数据的时候,就要注意了。remove之后,记得置为nil,才能立刻释放掉buff.
总结:
1.数组越界奔溃: index > _used+offset 或 index < 0。
2.如果想要内存记录释放,remove之后记得置nil.或者直接置nil.猜想Array的dealloc的方法会自动给所有元素发release消息。
 

NSmutableArray 的实现原理机制的更多相关文章

  1. Java提高篇——JVM加载class文件的原理机制

    在面试java工程师的时候,这道题经常被问到,故需特别注意. 1.JVM 简介 JVM 是我们Javaer 的最基本功底了,刚开始学Java 的时候,一般都是从“Hello World ”开始的,然后 ...

  2. JVM加载class文件的原理机制

    Java中的所有类,都需要由类加载器装载到JVM中才能运行.类加载器本身也是一个类,而它的工作就是把class文件从硬盘读取到内存中.在写程序的时候,我们几乎不需要关心类的加载,因为这些都是隐式装载的 ...

  3. 王家林的“云计算分布式大数据Hadoop实战高手之路---从零开始”的第十一讲Hadoop图文训练课程:MapReduce的原理机制和流程图剖析

    这一讲我们主要剖析MapReduce的原理机制和流程. “云计算分布式大数据Hadoop实战高手之路”之完整发布目录 云计算分布式大数据实战技术Hadoop交流群:312494188,每天都会在群中发 ...

  4. Glibc堆块的向前向后合并与unlink原理机制探究

    i春秋作家:Bug制造机 原文来自:Glibc堆块的向前向后合并与unlink原理机制探究 玩pwn有一段时间了,最近有点生疏了,调起来都不顺手了,所以读读malloc源码回炉一点一点总结反思下. U ...

  5. 研究一下Spark Hash Shuffle 和 SortShuffle 原理机制

    研究一下Spark Hash Shuffle 和 SortShuffle 原理机制研究一下Spark Hash Shuffle 和 SortShuffle 原理机制研究一下Spark Hash Shu ...

  6. JVM加载class文件的原理机制(转)

    JVM加载class文件的原理机制 1.Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中 2.java中的 ...

  7. java类什么时候加载?,加载类的原理机制是怎么样的?

    java类什么时候加载?,加载原理机制是怎么样的?   答: 很多人都不是很清楚java的class类什么时候加载在运行内存中,其实类加载的时间是发生在一下几种情况: 1.实例化对象时,就像sprin ...

  8. Java加载Class文件的原理机制

    详见:http://blog.sina.com.cn/s/blog_6cbfd2170100ljmp.html 1.Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器 ...

  9. Android10_原理机制系列_事件传递机制

    前言和概述 Android的输入设备,最常用的就是 触摸屏和按键 了.当然还有其他方式,比如游戏手柄,比如支持OTG设备,则可以链接鼠标.键盘等. 那么这些设备的操作 是如何传递到系统 并 控制界面的 ...

随机推荐

  1. drawText文字绘制知识

    drawText(String text, float x, float y, Paint paint) x,y是基于文字基本线的,而不是android坐标系的左上角. 使用staticLayout进 ...

  2. solr 7.x 查询及高亮

    查询时的api分为两种一种是万能的set,还有一种是setxxxquery @Test public void search2() throws Exception{ HttpSolrClient s ...

  3. Java网络编程注意事项1

    网络编程的基础知识 什么是计算机网络,就是把分布在不同地理区域的计算机与专门的外部设备通信线路互连成一个规模大.功能强的网络系统. 计算机网络主要能做些下面功能: 1)资源共享 2)信息传输与集中处理 ...

  4. Function函数

    一般大家都用这个写法来定义一个函数: function Name([parameters]){ functionBody }; //alert(typeof Name) // Function 当我们 ...

  5. DELPHI +ClientDataSet+DBGRIDEH 进行排序

    DELPHI +ClientDataSet+DBGRIDEH  进行排序因为使用了DBX+ClientDataSet,所以排序显得简单些,只需要设定几个属性就OK了.1.DbGridEH 中设定:Op ...

  6. 抛砖引玉 【镜像控件】 WPF实现毛玻璃控件不要太简单

    原文:抛砖引玉 [镜像控件] WPF实现毛玻璃控件不要太简单 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Vblegend_2013/articl ...

  7. TCP 报文段结构

      源端口.目标端口:计算机上的进程要和其他进程通信是要通过计算机端口的,而一个计算机端口某个时刻只能被一个进程占用,所以通过指定源端口和目标端口,就可以知道是哪两个进程需要通信.源端口.目标端口是用 ...

  8. NYOJ - 括号匹配(二)(经典dp)

    括号匹配(二) 时间限制:1000 ms | 内存限制:65535 KB 难度:6 描写叙述 给你一个字符串,里面仅仅包括"(",")","[&quo ...

  9. WPF中的3D Wireframe

    原文:WPF中的3D Wireframe WPF不支持画三维线,但开发人员提供了ScreenSpaceLines3D 类用于实现这个功能.我已经在程序中实现并成功显示3D Wireframe,并能够进 ...

  10. WPF 3D 获取鼠标在场景的3d坐标

    原文:WPF 3D 获取鼠标在场景的3d坐标 上一篇中我们谈到了WPF 3d做图的一些简单原理,这里我们简单介绍一下怎样获得鼠标在场景中的3d坐标,知道了3d坐标就可以进行很多操作了: 首先介绍一下3 ...