有關(guān) NSMutableArray 的原理

最近了解了 NSMutableArray 的原理,通過這篇文章了解到了其原理骄崩,這次我就將原文的 ARM64 討論部分省略辛友,對 NSMutableArray 的原理進(jìn)行自己的總結(jié)描述叉谜。

C語言中的數(shù)組

插入元素

也是我們常說的杰捂,當(dāng)數(shù)組需要插入時比驻,都需要對插入的下標(biāo)后的數(shù)組的元素進(jìn)行移動庆猫。同時刪除元素也是如此
刪除元素

這種情況下认轨,如果數(shù)組中的元素特別多,就會非常的耗時月培,那么我們使用 OC 中的 NSMutableArray 進(jìn)行上述操作時嘁字,會不會也和傳統(tǒng)的數(shù)組一樣?

OC 中的NSMutableArray

NSMutableArray 與 NSArray 的差別就在 Mutable(易變的)
通過某些方法我們得到了 NSMutableArray 類的 ivars杉畜,如下

@interface __NSArrayM : NSMutableArray
{
    unsigned long long _used;
    unsigned long long _doHardRetain:1;
    unsigned long long _doWeakAccess:1;
    unsigned long long _size:62;
    unsigned long long _hasObjects:1;
    unsigned long long _hasStrongReferences:1;
    unsigned long long _offset:62;
    unsigned long long _mutations;
    id *_list;
}

我們重點關(guān)注下面四個屬性

    unsigned long long _used;                     //元素的數(shù)量
    unsigned long long _size:62;                  //緩沖區(qū)的大小
    unsigned long long _offset:62;                //第一個元素在緩沖區(qū)的位置
    id *_list;                                    //指向緩沖區(qū)的指針

通過這四個屬性纪蜒,我們就可以實現(xiàn) Mutable ,首先為了達(dá)到 Mutable 的效果此叠,那么緩沖區(qū)的大小肯定不會是一個固定的值纯续,當(dāng)所有元素的內(nèi)存占滿了緩沖區(qū)后,它會以1.625倍的大小重新分配(為什么是1.625而不是2灭袁?原因) 同時猬错,當(dāng)它的大小變大后,它不會再縮小简卧,哪怕你把其中的所有元素清除兔魂。

在大小的問題解決后,NSMutableArray 到底是如何實現(xiàn)添加举娩、刪除元素的析校?
NSMutableArray 中的數(shù)據(jù)結(jié)構(gòu)為圓形緩沖區(qū),也就是一端到底后可以從另一段開始铜涉,抽象的將原先的線性的緩沖區(qū)首尾相連智玻。如果大家有刷算法題的話就知道這種方法在某些情況下很簡單也很好用
通過上面的四個屬性,我們可以自己手寫出其查詢方法 objectAtIndex

- (id)objectAtIndex:(NSUInteger)index
{
    if (_used <= index) {
        goto ThrowException;
    }
    
    //直接能得到的偏移量
    NSUInteger fetchOffset = _offset + index;
    //真正的偏移量
    NSUInteger realOffset = fetchOffset - (_size > fetchOffset ? 0 : _size);
    
    return _list[realOffset];
    
ThrowException:
    // exception throwing code
}

最關(guān)鍵的就是 fetchOffset 是否比 _size 大芙代,如果比 _size 大 因為是圓形緩沖區(qū)吊奢,所以需要從另一段接著計算,需要查詢的數(shù)據(jù)就在 fetchOffset - _size 上

我們可以通過例子來理解一下

當(dāng) fetchOffset < _size


fetchOffset < _size

假設(shè)我們需要獲取 _list[3],我們只需要計算好 fetchOffset = 6纹烹,此時 realOffset = fetchOffset =6 即可得到D

當(dāng) fetchOffset > _size


fetchOffset > _size

假設(shè)我們需要獲取_list[3],我們計算得到 fetchOffset = 10页滚,如果直接使用就會導(dǎo)致越界召边,所以我們計算 realOffset = fetchOffset - _size = 0 即可得到D

很好理解,當(dāng)我們需要在 NSMutableArray 的兩端刪除或者增加數(shù)據(jù)時裹驰,只需要修改 _size _user 和 _offset 即可隧熙,不需要對其它元素進(jìn)行操作,如下圖幻林。

刪除

增加

值得一提的是贞盯,它不會清理刪除的指針,也就是說即使你刪除了 _list[1]沪饺,但這個指針不會被刪除躏敢,但是你也無法得到被你刪除了的指針,因為屬性的改變整葡,你再次使用_list[1]時得到就是原先的_list[2]件余。

稍微復(fù)雜的情況就是在中間進(jìn)行刪除或者增加

這種情況和傳統(tǒng)的數(shù)組一樣,畢竟不是鏈表 無法避免的需要對其它的元素進(jìn)行操作遭居,但是其內(nèi)部會添加一個判斷蛾扇,選擇盡量少的操作來達(dá)到目的,比如下圖不會選擇從右方進(jìn)行操作
刪除中間元素
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末魏滚,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子坟漱,更是在濱河造成了極大的恐慌鼠次,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芋齿,死亡現(xiàn)場離奇詭異腥寇,居然都是意外死亡,警方通過查閱死者的電腦和手機觅捆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門赦役,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人栅炒,你說我怎么就攤上這事掂摔。” “怎么了赢赊?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵乙漓,是天一觀的道長。 經(jīng)常有香客問我释移,道長叭披,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任玩讳,我火速辦了婚禮涩蜘,結(jié)果婚禮上嚼贡,老公的妹妹穿的比我還像新娘。我一直安慰自己同诫,他們只是感情好粤策,可當(dāng)我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著剩辟,像睡著了一般掐场。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贩猎,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天熊户,我揣著相機與錄音,去河邊找鬼吭服。 笑死嚷堡,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的艇棕。 我是一名探鬼主播蝌戒,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼沼琉!你這毒婦竟也來了北苟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤打瘪,失蹤者是張志新(化名)和其女友劉穎友鼻,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闺骚,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡彩扔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了僻爽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虫碉。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖胸梆,靈堂內(nèi)的尸體忽然破棺而出敦捧,到底是詐尸還是另有隱情,我是刑警寧澤碰镜,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布绞惦,位于F島的核電站,受9級特大地震影響洋措,放射性物質(zhì)發(fā)生泄漏济蝉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望王滤。 院中可真熱鬧贺嫂,春花似錦、人聲如沸雁乡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽踱稍。三九已至曲饱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間珠月,已是汗流浹背扩淀。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留啤挎,地道東北人驻谆。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像庆聘,于是被迫代替她去往敵國和親胜臊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容