iOS學(xué)習(xí)心得之:MRC和ARC簡單理解

OC內(nèi)存管理有兩種模式:
ARC automatic reference counting 自引用用計(jì)數(shù)
MRC manual reference counting 手動(dòng)引用計(jì)數(shù)

在2011年、IOS5之前,OC的開發(fā)只支持MRC模式。
也就是只支持手動(dòng)引用計(jì)數(shù)。
當(dāng)時(shí)每當(dāng)一個(gè)新的指針引用了一塊堆空間(也就是對(duì)象)
就必須手動(dòng)的把此塊堆空間內(nèi)的 retainCount + 1。
具體操作:

Person* p = [Person new];//默認(rèn)就是1 ,所以這里的p不需要手動(dòng)操作。

Person* p2 = p;
[p2 retain];//將retainCount的值+1;

當(dāng)p2指針不使用此堆空間了。要手動(dòng)把 retainCount 值 - 1
[p2 release];

p不用了,也需要release
[p release];

手動(dòng)計(jì)數(shù)器使用規(guī)則:
誰用誰retain,誰不用誰release。

關(guān)于內(nèi)存釋放的本質(zhì):
當(dāng)一塊內(nèi)存釋放的時(shí)候,本質(zhì)上只是給這部分字節(jié)打了標(biāo)簽。并沒有把字節(jié)里的二進(jìn)制數(shù)據(jù)全部清成0或者1.
所以,當(dāng)一塊內(nèi)存說是釋放了,但如果沒有其他的二進(jìn)制數(shù)據(jù)去填充它,那么它的內(nèi)部數(shù)據(jù)是一直存在的。

內(nèi)存釋放,數(shù)據(jù)仍然存在,就會(huì)出現(xiàn)一種僵尸對(duì)象的問題。
什么是僵尸對(duì)象?堆空間已經(jīng)被標(biāo)記清空,能被其他數(shù)據(jù)使用。但此時(shí)此刻,新的二進(jìn)制數(shù)據(jù)還沒有進(jìn)來。
我們此時(shí)用一個(gè)指針指向已經(jīng)標(biāo)記釋放了的堆空間。這個(gè)就叫僵尸對(duì)象和野指針。

    At mrc model:
    Person* p = [Person new];
    [p release];//指針指向的堆空間,在代碼級(jí)別已經(jīng)被釋放。
    p.name = @“內(nèi)存就沒有釋放的概念,只是打了可以被其他數(shù)據(jù)填充的標(biāo)簽”;
    NSLog(@“%@”,p.name);//但如果沒有其他的數(shù)據(jù)填充這塊空間,所以在某種條件下(沒被其他數(shù)據(jù)填充)數(shù)據(jù)仍然存在??梢岳^續(xù)訪問。

關(guān)于dealloc函數(shù)釋放堆空間。
在手動(dòng)模式下:
1、可以直接調(diào)用dealloc 強(qiáng)制標(biāo)記當(dāng)前堆空間直接被釋放,而不用去管retainCount是否是0.
2、每次調(diào)用release 把 retainCount-1 的同時(shí)會(huì)判斷retainCount的最終值是否是0,是0接著調(diào)用dealloc函數(shù)標(biāo)記當(dāng)前堆空間釋放。

如何在手動(dòng)模式下,避免已經(jīng)被標(biāo)記的堆空間被指針引用并使用呢?
    因?yàn)楸粯?biāo)記釋放的堆空間,會(huì)在任意時(shí)間內(nèi)被其他數(shù)據(jù)使用。所以這對(duì)這個(gè)指針來說是不安全的。
有兩種解決方式:
1、打開僵尸對(duì)象檢查機(jī)制【一但這塊堆空間被標(biāo)記釋放了,那么所有的指針都不能使用這塊空間】
2、將你認(rèn)為可能是指向僵尸堆空間的指針設(shè)置成nil
    OC的實(shí)例函數(shù)比較過硬,當(dāng)傳入的第一個(gè)參數(shù),也就是self對(duì)象為nil時(shí),函數(shù)也不會(huì)報(bào)錯(cuò)。
    這在.net里會(huì)爆出 【未將對(duì)象引用設(shè)置到對(duì)象實(shí)例】 的錯(cuò)誤的。

ARC:automatic reference counting 自動(dòng)引用計(jì)數(shù)
所有堆空間在新指針引用時(shí)的 retainCount+1 在指針不引用時(shí) retainCount-1。
自動(dòng)維護(hù)引用計(jì)數(shù),并標(biāo)記釋放當(dāng)前堆空間。不需要程序員去關(guān)心。

補(bǔ)充一點(diǎn):
當(dāng)一塊堆空間被標(biāo)記可以刪除之后,即使暫時(shí)沒有新的數(shù)據(jù)填充這塊空間。原來空間的數(shù)據(jù)也不能【復(fù)活】過來重新使用。
eg:

//引用計(jì)數(shù)1
Person* p = [Person new];
//引用計(jì)數(shù)jian-1,為0 觸發(fā)dealloc。標(biāo)記釋放
[p release];//
[p retain];//此塊堆空間已經(jīng)被標(biāo)記釋放,所以對(duì)堆內(nèi)的操作都將無效。數(shù)據(jù)馬上就要被釋放了,還操作個(gè)毛線。   
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 多線程、特別是NSOperation 和 GCD 的內(nèi)部原理。運(yùn)行時(shí)機(jī)制的原理和運(yùn)用場(chǎng)景。SDWebImage的原...
    LZM輪回閱讀 2,116評(píng)論 0 12
  • 史上最全的iOS面試題及答案 iOS面試小貼士———————————————回答好下面的足夠了----------...
    Style_偉閱讀 2,565評(píng)論 0 35
  • 內(nèi)存管理 簡述OC中內(nèi)存管理機(jī)制。與retain配對(duì)使用的方法是dealloc還是release,為什么?需要與a...
    丶逐漸閱讀 2,080評(píng)論 1 16
  • 本文首發(fā)于我的個(gè)人博客:「程序員充電站」[https://itcharge.cn]文章鏈接:「?jìng)魉烷T」[https...
    ITCharge閱讀 32,611評(píng)論 47 185
  • iOS內(nèi)存管理 概述 什么是內(nèi)存管理 應(yīng)用程序內(nèi)存管理是在程序運(yùn)行時(shí)分配內(nèi)存(比如創(chuàng)建一個(gè)對(duì)象,會(huì)增加內(nèi)存占用)與...
    蚊香醬閱讀 5,807評(píng)論 8 119

友情鏈接更多精彩內(nèi)容