您好,登錄后才能下訂單哦!
1.內(nèi)存泄露
一般我們常說的內(nèi)存泄漏是指堆內(nèi)存的泄漏。堆內(nèi)存是指程序從堆中分配的,大小任意的(內(nèi)存塊的大小可以在程序運(yùn)行期決定),使用完后必須顯式釋放的內(nèi)存。應(yīng)用程序一般使用malloc,calloc,realloc等函數(shù)(C++中使用new操作符)從堆中分配到一塊內(nèi)存,使用完后,程序必須負(fù)責(zé)相應(yīng)的調(diào)用free或delete釋放該內(nèi)存塊,否則,這塊內(nèi)存就不能被再次使用,我們就說這塊內(nèi)存泄漏了。
2. 內(nèi)存管理
堆中的內(nèi)存都是手動(dòng)開辟和手動(dòng)釋放的。因此我們要時(shí)刻統(tǒng)計(jì)堆的指針有哪些是指向同一個(gè)的。再釋放時(shí),確認(rèn)所有指向這個(gè)堆的指針,都已經(jīng)用完了,不再使用。但這個(gè)存在先天的不足,畢竟程序員在統(tǒng)計(jì)指針是否用完時(shí),受到多方面的影響而不能正確統(tǒng)計(jì),程序在聯(lián)合開發(fā)的時(shí)候,指向同一個(gè)的堆的指針就很難統(tǒng)計(jì),因此必須有一個(gè)合理的方法來管理內(nèi)存。
3. 理解內(nèi)存管理到底干了什么?
OC中的內(nèi)存管理實(shí)際上就是一種PV操作,就是對(duì)計(jì)數(shù)器的加減操作。基類NSObject存在一個(gè)計(jì)數(shù)器retainCount,并會(huì)被子類所繼承。alloc創(chuàng)建對(duì)象時(shí),計(jì)數(shù)器+1,retain純粹的計(jì)數(shù)器+1,release將計(jì)數(shù)器減1,不是真的free掉一個(gè)對(duì)象,release時(shí)本著個(gè)人顧個(gè)人的原則。
4. release原則(黃金法則)
當(dāng)我們用alloc,retain,new,copy,mutablecopy這些函數(shù)創(chuàng)建地址付給指針時(shí),需要用release或者autorelease釋放。釋放的時(shí)候,每個(gè)指針誰創(chuàng)建的誰釋放,不能去釋放別人創(chuàng)建的指針。
5. 成員變量為對(duì)象的set函數(shù)
一個(gè)類的成員變量為另一個(gè)類的對(duì)象時(shí),為了考慮內(nèi)存管理,set函數(shù)的一般寫法,以Car類擁有Engine對(duì)象作為成員變量為例:
-(void)setEngine:(Engine *)newengine
{
if(engine!=newengine){ //判斷是否自我賦值
[engine release]; //若為對(duì)象賦新值,先release舊的
engine=[newEngine retain]; //賦新值且retain一下計(jì)數(shù)器+1
}
return;
}
這個(gè)set函數(shù)充分的考慮到了,自我賦值和對(duì)象取新值的情況,engine為空時(shí),[engine release]執(zhí)行一次,但不會(huì)產(chǎn)生效果,所以不會(huì)出現(xiàn)錯(cuò)誤。因?yàn)?/span>OC在創(chuàng)建對(duì)象時(shí),成員變量默認(rèn)為nil,[nil release]能夠執(zhí)行,但是沒有效果,即不會(huì)對(duì)計(jì)數(shù)器產(chǎn)生影響。但是存在一個(gè)問題,就是賦新值后retain后,使用完成后會(huì)發(fā)現(xiàn)無法對(duì)其release,因?yàn)?/span>car類對(duì)象一直使用著這個(gè)值,car對(duì)象銷毀,才執(zhí)行retain一次,減少engine計(jì)數(shù)器一次。因此必須重寫Car類的dealloc函數(shù),在car對(duì)象釋放時(shí),release一下engine,以對(duì)應(yīng)set函數(shù)中的retain,滿足黃金法則。
重寫的dealloc函數(shù)為:
-(void)dealloc //car的對(duì)象釋放時(shí),自動(dòng)調(diào)用,類似析構(gòu)函數(shù)
{
[engine release]; //self.engine=nil;作用相同(調(diào)用set函數(shù))
[surper dealloc]; //模擬C++析構(gòu)時(shí),調(diào)用父類的析構(gòu)函數(shù)
return;
}
6. 特殊成員變量的點(diǎn)語法
不同于普通變量,set和get函數(shù)封裝應(yīng)為:
@property (retain) Engine * engine;
@synthesize engine;
這樣就不用麻煩的自己書寫set函數(shù)了。一個(gè)類的成員是另一個(gè)類時(shí),此時(shí) 的set函數(shù)會(huì)與以前的普通成員邊量set函數(shù)大有不同,set函數(shù)書寫為內(nèi)存 管路版本使用時(shí),一定要重寫dealloc函數(shù),處理成員對(duì)象的最后一次release。
7. atuorelease和atuoreleasepool
新版的自動(dòng)釋放池寫法為;
@autoreleasepool
{
}
釋放池作為一個(gè)關(guān)鍵字存在,老版本的釋放池的書寫更易于理解,寫法如下:
NSAutorelease *pool = [[NSAutoreleasePool alloc]init];
…………
[pool release];
可以將pool看為一個(gè)數(shù)組,將relase的對(duì)象裝在這個(gè)數(shù)組中,等到釋放池 釋放的時(shí)候,才把池中的對(duì)象全部執(zhí)行一次release。
8. 以對(duì)象dog為例,使用自動(dòng)釋放池release:
[dog autorelease]; //自動(dòng)釋放 延遲釋放
這里是將dog地址添加到pool中,pool執(zhí)行release時(shí),才把池中的對(duì)象全 部執(zhí)行一次release。在這之前,計(jì)數(shù)器并沒有真正的減一,pool釋放的時(shí) 候dog的計(jì)數(shù)器才會(huì)真正的減一。
9. 不到萬不得已的時(shí)候,千萬不要用autoreleasepool。
IOS中每一個(gè)觸發(fā)周期,系統(tǒng)都會(huì)自動(dòng)創(chuàng)建一個(gè)自動(dòng)釋放池,在周期結(jié)束時(shí), 就會(huì)釋放這個(gè)pool。autorelease自動(dòng)匹配最近的一個(gè)pool,我們并不能控 制其在我們想要釋放的時(shí)候才釋放。
+函數(shù)創(chuàng)建一個(gè)對(duì)象時(shí),并不能確定何時(shí)釋放對(duì)象,因此我們?cè)?/span>pool釋放時(shí), 再釋放這個(gè)對(duì)象,避免錯(cuò)誤。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。