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