古老的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. 关于HierarchyViewer的使用

    在学习ViewGroup和Layout时我们可能会有一个疑问,如果我在Xml布局文件中不放置Layout,直接放TextView等组件的时候,它是用什么方式布局的?还有要学习别人优秀的布局怎么办? H ...

  2. WPF 获得当前输入法语言区域

    原文:WPF 获得当前输入法语言区域 本文告诉大家如何获得 WPF 输入法的语言区域 需要使用 user32 的方法,很简单,请看下面 [DllImport("user32.dll" ...

  3. mongoose ObjectId.toString()

    node中一般我们经常对id进行判断,有的id是string类型,有的是ObjectId(''),这时候就可以使用mongoose的toString方法,将它转换成string

  4. iOS的安全性和越狱

    提到越狱,很多人第一反应大概是免费的游戏和 app. 作为软件从业人员,深知中国的大环境的特殊性.内有用户想吃免费午餐的不良付费习惯,外有行业内大头诸如某讯对创新的绞杀.大家对越狱是为了免费.盗版软件 ...

  5. 2.RabbitMQ的quick start

    1.首先要安装 RabbitMQ Client 2.创建一个控制台项目 取名 Publisher代码如下: using RabbitMQ.Client; using System; using Sys ...

  6. uwp - 获取当前屏幕宽高/应用宽高

    原文:uwp - 获取当前屏幕宽高/应用宽高 public static Size GetScreen() { var applicationView = ApplicationView.GetFor ...

  7. 信号、系统与滤波器设计(matlab)

    0. 基本概念 AWG:Additive White(zero-mean) Gaussian,可加白噪声: AWGN:Additive White(zero-mean) Gaussian Noise ...

  8. 潜移默化学会WPF(转载篇)--屏幕显示Label,鼠标移上去变成textBox

    原文:潜移默化学会WPF(转载篇)--屏幕显示Label,鼠标移上去变成textBox <Window x:Class="WpfApplication1.Window1" x ...

  9. H3C交换机配置ACL禁止vlan间互访

    1.先把基础工作做好,就是配置VLAN,配置Trunk,确定10个VLAN和相应的端口都正确.假设10个VLAN的地址分别是192.168.10.X,192.168.20.X......192.168 ...

  10. jquery子元素过滤器

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...