1.內存泄露
為慶安等地區(qū)用戶提供了全套網(wǎng)頁設計制作服務,及慶安網(wǎng)站建設行業(yè)解決方案。主營業(yè)務為做網(wǎng)站、網(wǎng)站制作、慶安網(wǎng)站設計,以傳統(tǒng)方式定制建設網(wǎng)站,并提供域名空間備案等一條龍服務,秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!一般我們常說的內存泄漏是指堆內存的泄漏。堆內存是指程序從堆中分配的,大小任意的(內存塊的大小可以在程序運行期決定),使用完后必須顯式釋放的內存。應用程序一般使用malloc,calloc,realloc等函數(shù)(C++中使用new操作符)從堆中分配到一塊內存,使用完后,程序必須負責相應的調用free或delete釋放該內存塊,否則,這塊內存就不能被再次使用,我們就說這塊內存泄漏了。
2. 內存管理
堆中的內存都是手動開辟和手動釋放的。因此我們要時刻統(tǒng)計堆的指針有哪些是指向同一個的。再釋放時,確認所有指向這個堆的指針,都已經用完了,不再使用。但這個存在先天的不足,畢竟程序員在統(tǒng)計指針是否用完時,受到多方面的影響而不能正確統(tǒng)計,程序在聯(lián)合開發(fā)的時候,指向同一個的堆的指針就很難統(tǒng)計,因此必須有一個合理的方法來管理內存。
3. 理解內存管理到底干了什么?
OC中的內存管理實際上就是一種PV操作,就是對計數(shù)器的加減操作?;怤SObject存在一個計數(shù)器retainCount,并會被子類所繼承。alloc創(chuàng)建對象時,計數(shù)器+1,retain純粹的計數(shù)器+1,release將計數(shù)器減1,不是真的free掉一個對象,release時本著個人顧個人的原則。
4. release原則(黃金法則)
當我們用alloc,retain,new,copy,mutablecopy這些函數(shù)創(chuàng)建地址付給指針時,需要用release或者autorelease釋放。釋放的時候,每個指針誰創(chuàng)建的誰釋放,不能去釋放別人創(chuàng)建的指針。
5. 成員變量為對象的set函數(shù)
一個類的成員變量為另一個類的對象時,為了考慮內存管理,set函數(shù)的一般寫法,以Car類擁有Engine對象作為成員變量為例:
-(void)setEngine:(Engine *)newengine
{
if(engine!=newengine){ //判斷是否自我賦值
[engine release]; //若為對象賦新值,先release舊的
engine=[newEngine retain]; //賦新值且retain一下計數(shù)器+1
}
return;
}
這個set函數(shù)充分的考慮到了,自我賦值和對象取新值的情況,engine為空時,[engine release]執(zhí)行一次,但不會產生效果,所以不會出現(xiàn)錯誤。因為OC在創(chuàng)建對象時,成員變量默認為nil,[nil release]能夠執(zhí)行,但是沒有效果,即不會對計數(shù)器產生影響。但是存在一個問題,就是賦新值后retain后,使用完成后會發(fā)現(xiàn)無法對其release,因為car類對象一直使用著這個值,car對象銷毀,才執(zhí)行retain一次,減少engine計數(shù)器一次。因此必須重寫Car類的dealloc函數(shù),在car對象釋放時,release一下engine,以對應set函數(shù)中的retain,滿足黃金法則。
重寫的dealloc函數(shù)為:
-(void)dealloc //car的對象釋放時,自動調用,類似析構函數(shù)
{
[engine release]; //self.engine=nil;作用相同(調用set函數(shù))
[surper dealloc]; //模擬C++析構時,調用父類的析構函數(shù)
return;
}
6. 特殊成員變量的點語法
不同于普通變量,set和get函數(shù)封裝應為:
@property (retain) Engine * engine;
@synthesize engine;
這樣就不用麻煩的自己書寫set函數(shù)了。一個類的成員是另一個類時,此時 的set函數(shù)會與以前的普通成員邊量set函數(shù)大有不同,set函數(shù)書寫為內存 管路版本使用時,一定要重寫dealloc函數(shù),處理成員對象的最后一次release。
7. atuorelease和atuoreleasepool
新版的自動釋放池寫法為;
@autoreleasepool
{
}
釋放池作為一個關鍵字存在,老版本的釋放池的書寫更易于理解,寫法如下:
NSAutorelease *pool = [[NSAutoreleasePool alloc]init];
…………
[pool release];
可以將pool看為一個數(shù)組,將relase的對象裝在這個數(shù)組中,等到釋放池 釋放的時候,才把池中的對象全部執(zhí)行一次release。
8. 以對象dog為例,使用自動釋放池release:
[dog autorelease]; //自動釋放 延遲釋放
這里是將dog地址添加到pool中,pool執(zhí)行release時,才把池中的對象全 部執(zhí)行一次release。在這之前,計數(shù)器并沒有真正的減一,pool釋放的時 候dog的計數(shù)器才會真正的減一。
9. 不到萬不得已的時候,千萬不要用autoreleasepool。
IOS中每一個觸發(fā)周期,系統(tǒng)都會自動創(chuàng)建一個自動釋放池,在周期結束時, 就會釋放這個pool。autorelease自動匹配最近的一個pool,我們并不能控 制其在我們想要釋放的時候才釋放。
+函數(shù)創(chuàng)建一個對象時,并不能確定何時釋放對象,因此我們在pool釋放時, 再釋放這個對象,避免錯誤。
另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。