NSmutableArray 的实现原理机制

古老的C数组:

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

NSMutableArray的内部数据结构如下:

P158


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

删除元素

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

 

执行两次 remove的实现:
P159

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

插入元素

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

 

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

删除元素

[arr removeObjecAtIndex:3];

 

实现:
 
P157
 
删除头尾元素直接修改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消息。

 

转载于:https://www.cnblogs.com/firstrate/p/8313443.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值