詳談Objective-C內(nèi)存管理機(jī)制
Objective-C內(nèi)存管理機(jī)制是本文要介紹的內(nèi)容,最近iphone平臺(tái)比較火,大家都一窩蜂的上了。不過(guò)貌似好多都是從Java轉(zhuǎn)過(guò)來(lái)的程序員,用慣了Java的,對(duì)Objective-C可能會(huì)不大適應(yīng),特別是Objective-C的內(nèi)存管理機(jī)制。
手機(jī)平臺(tái)不同于計(jì)算機(jī),雖然開(kāi)發(fā)的應(yīng)用都是小巧的應(yīng)用,但是由于手機(jī)硬件上的局限性,如 果不對(duì)內(nèi)存好好管理的話,還是會(huì)出很多問(wèn)題的,特別是習(xí)慣了垃圾回收機(jī)制的Java程序員,最容易忽視這個(gè)問(wèn)題。希望下面這篇文章能對(duì)大家有所幫助。
Objective-C使用了一種叫做持有計(jì)數(shù)(Retain Count)的機(jī)制來(lái)管理內(nèi)存中的對(duì)象。
在 Objective-C中每個(gè)對(duì)象都對(duì)應(yīng)著他們自己的持有計(jì)數(shù)(Retain Count),持有計(jì)數(shù)可以理解為一個(gè)整數(shù)計(jì)數(shù)器,當(dāng)使用alloc方法創(chuàng)建對(duì)象的時(shí)候,持有計(jì)數(shù)會(huì)自動(dòng)設(shè)置為1。當(dāng)你向一個(gè)對(duì)象發(fā)送retain消息 時(shí),持有計(jì)數(shù)數(shù)值會(huì)增加。相反,當(dāng)你像一個(gè)對(duì)象發(fā)送release消息時(shí),持有計(jì)數(shù)數(shù)值會(huì)減小。當(dāng)對(duì)象的持有計(jì)數(shù)變?yōu)?的時(shí)候,對(duì)象會(huì)釋放自己所占用的內(nèi) 存。
為什么要使用持有計(jì)數(shù)這個(gè)概念呢?
想象一下,有時(shí)候你會(huì)在多個(gè)不同對(duì)象中引用同一個(gè)對(duì)象。當(dāng)你在一個(gè)地方 釋放這個(gè)公用對(duì)象 時(shí),勢(shì)必會(huì)對(duì)其他引用這個(gè)公用對(duì)象的對(duì)象產(chǎn)生影響。但是如果每當(dāng)你引用這個(gè)公用對(duì)象時(shí),都向持有計(jì)數(shù)發(fā)送一個(gè)retain消息,釋放一個(gè)對(duì)象時(shí),發(fā)送一個(gè) release消息。這樣對(duì)象的持有計(jì)數(shù)會(huì)記錄到底有多少個(gè)對(duì)象引用了它自己。當(dāng)它的持有計(jì)數(shù)變?yōu)?的時(shí)候,這意味著沒(méi)有其他對(duì)象引用這個(gè)對(duì)象了,那么它 可以安全的釋放自己所占用的內(nèi)存。
對(duì)上面情況的一個(gè)比較形象的比喻,假設(shè)我們有一條狗和幾個(gè)用繩子牽著這條狗的人,那么不到***一個(gè)人松掉手中的繩子,這只狗是不能獲得自由的。而持有計(jì)數(shù)的作用就是記錄了到底有多少個(gè)人牽著繩子。
不 同于Java的垃圾回收,Objective-C提供了持有計(jì)數(shù)這種特別機(jī)制。它給予了開(kāi)發(fā)者們更多的控制權(quán),去控制什么時(shí)候和怎么樣來(lái)釋放一個(gè)對(duì)象,但 是這同時(shí)需要開(kāi)發(fā)者們更加的細(xì)心。如果你過(guò)早的釋放了一個(gè)對(duì)象,那么你的應(yīng)用程序很可能會(huì)意外宕掉。相反,如果你很長(zhǎng)時(shí)間不釋放對(duì)象占用的內(nèi)存,那么應(yīng)用 程序在運(yùn)行了一段時(shí)間后很可能會(huì)造成內(nèi)存泄漏。
數(shù)組(Array)是一個(gè)比較特別的例子,當(dāng)你往數(shù)組里面添加一個(gè)對(duì)象時(shí)。數(shù)組里面存儲(chǔ)的并不是這個(gè)對(duì)象的拷貝,而只是一個(gè)指向該對(duì)象的指針。數(shù)組在保存 這個(gè)指針的同時(shí)會(huì)向指針?biāo)傅膶?duì)象發(fā)送一個(gè)retain消息,相應(yīng)的,對(duì)象的持有計(jì)數(shù)會(huì)增加。將對(duì)象從數(shù)組中移除的時(shí)候,同樣會(huì)向?qū)ο蟀l(fā)送release 消息,對(duì)象的持有計(jì)數(shù)會(huì)減小。當(dāng)我們釋放這個(gè)數(shù)組時(shí),會(huì)向保存在這個(gè)數(shù)組中的所有對(duì)象發(fā)送release消息??聪旅娴膬蓚€(gè)例子:
1、沒(méi)有釋放內(nèi)存的版本
- array = [[NSMutableArray alloc] init];
- for ( i = 0; i < 10; i++) {
- newNumber = [[NSNumber alloc]initWithInt:(i * 3)];
- [array addObject:newNumber];
- }
上 面的代碼在創(chuàng)建newNumber對(duì)象時(shí),向?qū)ο蟮陌l(fā)送了retain消息,對(duì)象的持有計(jì)數(shù)變?yōu)?。當(dāng)向array中添加這個(gè)對(duì)象的引用時(shí),又向?qū)ο蟀l(fā)送 了一次retain消息,這樣對(duì)象的持有計(jì)數(shù)就變?yōu)?了,在使用完array時(shí),我們會(huì)習(xí)慣性的釋放掉array,但這樣并不會(huì)釋放array所持有的對(duì) 象,而只是使所有對(duì)象的持有計(jì)數(shù)變?yōu)?,這些對(duì)象依然會(huì)占用著內(nèi)存。
2、釋放內(nèi)存的版本
- for (i = 0; i < 10; i++) {
- newNumber = [[NSNumber alloc]initWithInt:(i*3)];
- [array addObject:newNumber];
- [newNumber release];
- }
小結(jié):關(guān)于詳談Objective-C內(nèi)存管理機(jī)制的內(nèi)容介紹完了,希望通過(guò)本文的學(xué)習(xí)能對(duì)你有所幫助!