OC內(nèi)存管理有兩種模式:
ARC automatic reference counting 自引用用計(jì)數(shù)
MRC manual reference counting 手動(dòng)引用計(jì)數(shù)
在2011年、IOS5之前,OC的開(kāi)發(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ī)則:
誰(shuí)用誰(shuí)retain彤避,誰(shuí)不用誰(shuí)release傅物。
關(guān)于內(nèi)存釋放的本質(zhì):
當(dāng)一塊內(nèi)存釋放的時(shí)候,本質(zhì)上只是給這部分字節(jié)打了標(biāo)簽琉预。并沒(méi)有把字節(jié)里的二進(jìn)制數(shù)據(jù)全部清成0或者1.
所以董饰,當(dāng)一塊內(nèi)存說(shuō)是釋放了,但如果沒(méi)有其他的二進(jìn)制數(shù)據(jù)去填充它圆米,那么它的內(nèi)部數(shù)據(jù)是一直存在的卒暂。
內(nèi)存釋放,數(shù)據(jù)仍然存在娄帖,就會(huì)出現(xiàn)一種僵尸對(duì)象的問(wèn)題也祠。
什么是僵尸對(duì)象?堆空間已經(jīng)被標(biāo)記清空近速,能被其他數(shù)據(jù)使用诈嘿。但此時(shí)此刻堪旧,新的二進(jìn)制數(shù)據(jù)還沒(méi)有進(jìn)來(lái)。
我們此時(shí)用一個(gè)指針指向已經(jīng)標(biāo)記釋放了的堆空間奖亚。這個(gè)就叫僵尸對(duì)象和野指針淳梦。
At mrc model:
Person* p = [Person new];
[p release];//指針指向的堆空間,在代碼級(jí)別已經(jīng)被釋放昔字。
p.name = @“內(nèi)存就沒(méi)有釋放的概念爆袍,只是打了可以被其他數(shù)據(jù)填充的標(biāo)簽”;
NSLog(@“%@”,p.name);//但如果沒(méi)有其他的數(shù)據(jù)填充這塊空間,所以在某種條件下(沒(méi)被其他數(shù)據(jù)填充)數(shù)據(jù)仍然存在李滴◇χ妫可以繼續(xù)訪問(wèn)。
關(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è)指針來(lái)說(shuō)是不安全的斥季。
有兩種解決方式:
1、打開(kāi)僵尸對(duì)象檢查機(jī)制【一但這塊堆空間被標(biāo)記釋放了累驮,那么所有的指針都不能使用這塊空間】
2酣倾、將你認(rèn)為可能是指向僵尸堆空間的指針設(shè)置成nil
OC的實(shí)例函數(shù)比較過(guò)硬,當(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í)沒(méi)有新的數(shù)據(jù)填充這塊空間秕衙。原來(lái)空間的數(shù)據(jù)也不能【復(fù)活】過(guò)來(lái)重新使用抬伺。
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)的操作都將無(wú)效妓笙。數(shù)據(jù)馬上就要被釋放了,還操作個(gè)毛線能岩。