天天看點

OC 記憶體管理(初級)

初級:

記憶體問題展現在兩個方面

1.記憶體溢出:一旦超出記憶體上限,程式就會 Crash

2.野指針異常:對象記憶體空間已經被系統回收,仍然使用指針操作這塊記憶體.野指針異常是程式 crash 的主要原因.

記憶體管理的方式:

垃圾回收  (gc)

MRC (Manual Reference Count)  人工引用計數

ARC (Auto  Reference Count)   自動引用計數

gc : 程式員隻需要開辟記憶體空間,不需要用代碼顯示地釋放,系統來判斷哪些空    間不再被使用,并回收這些記憶體空間,以便再次配置設定.整個回收的過程不需要寫任何代碼,由系統自動完成垃圾回收.

MRC :記憶體的開辟和釋放都由程式代碼進行控制.相對于垃圾回收來說,對記憶體的控制更加靈活,可以在自己需要釋放的時候及時釋放,對程式員的要求較高,程式員要熟悉記憶體管理的機制.

ARC :iOS 5.0的編譯器特性,它允許使用者隻開辟空間,不用去釋放空間.它不是垃圾回收!它的本質還是 MRC, 隻是編譯器幫程式員預設加了釋放的代碼.

iOS 支援兩種記憶體管理方式: ARC 和 MRC

MRC 的記憶體管理機制是:引用計數

ARC 是基于 MRC

引用計數:

OC 采用引用計數機制管理記憶體,當一個新的引用指向對象時,引用計數器就遞增,當去掉一個引用時,引用計數就遞增.當引用計數到零時,該對象就釋放占用的資源.

影響引用計數的方法:

1. +alloc :  開辟記憶體空間,讓被開辟的記憶體空間的引用計數變為1. 這是由0到 1得過程.

2. -retain :  引用計數加1,如果記憶體空間之前引用計數為1,retain 之後變為2,如果引用計數是5,retain 之後變為6.( 相等于自增 )

3. -copy :  把某一記憶體區域的内容拷貝一份,拷貝到新的記憶體空間裡去,被拷貝區域的引用計數不變,新的記憶體區域的引用計數為1.( 原有的不變,新的加1) (淺複制引用計數加1,深複制不變)    淺 copy 相等于  retain 一下

4 .-release : 引用計數減1, 如果記憶體空間之前引用計數為4,release 之後變為3,如果之前引用計數為1,release 之後為0,記憶體被系統回收.( 相等于自減,不是立即減1)

最後一次 release 後,即變為0之後,不能在使用指針和對象的任何東西,使用 的是野指針!也不能進行列印,這是一個錯誤的寫法了!

5. -autorelease : 未來的某一時刻引用計數減1.如果記憶體之前引用計數為4,     autorelease之後仍然是4,未來某個時刻會變為3.

dealloc:

- dealloc 是繼承自父類的方法,當對象引用計數為0的時候,由對象自動調用.

我們可以在dealloc 中列印一句話,驗證對象引用計數是否降為0.

- (void)dealloc

{

     NSLog(@“%@被銷毀了”,self);

     [super dealloc]; // 一定寫在下面 , 先銷毀自己變量的 , 最後銷毀父類變量

}

autoreleasepool 的使用:

通過autoreleasepool 控制 autorelease 對象的釋放.

向一個對象發送 autorelease 消息,這個對象何時釋放,取決于autoreleasepool 

先寫的先進來,但是後釋放

寫法:

NSAutoreleasePool *pool = [ [NSAutoreleasePool alloc]  init];

Person *p =[ [Person alloc]  init];//retainCount為1

[p retain];//retainCount 為2

[p autorelease];//retainCount 為2  未來的某個時刻釋放

[pool release];

NSLog(@“%d”,[p retainCount]);//列印結果為1

在 iOS5之後,不在推薦使用 NSAutoreleasePool 類, 使用@ autoreleasepool{}替代.

寫法為:

autoreleasepool

{

     [p  autorelease];

     [p  autorelease];

}

出了大括号,自動釋放池向各個對象發送 release 消息.

OC 記憶體管理(初級)

記憶體管理的原則:

1.引用計數的增加和減少相等,當引用計數降為0之後,不應該再使用這塊記憶體空間.

2.凡是使用了(隻要你看到了)alloc retain 或 copy 這三個關鍵字,那麼他們肯定是讓記憶體增加了,就需要使用 release 或 autorelease 讓記憶體的引用計數減少.這一段代碼内,增加和減少的次數要相等.

//當 release 和 autorelease 釋放成0的時候,自動掉 dealloc