天天看點

黑馬程式員--OC之記憶體管理

------ Java教育訓練、Android教育訓練、iOS教育訓練、.Net教育訓練、期待與您交流! -------

OC中的記憶體管理

1.為什麼要管理記憶體

系統資源有限,會為每個程式配置設定30M的記憶體,超過20M會收到記憶體警告,超過30M,sorry 系統将會終止你的應用程式。

2.怎麼樣管理記憶體

  1. 1)  記憶體管理機制

     ObjC中提供了一個機制來實作上面提到的這個邏輯模型,它被稱為“引用計數”(retain counting):

· 每一個對象都有一個引用計數(retain count) 

· 對象被建立的時候,引用計數的值是1 

· 當引用計數值是0的時候,對象将被系統統一銷毀 

· 我們可以通過調用一些方法來操作引用計數的值

獲得所有權的方法:

· alloc:為一個新對象配置設定記憶體,并且它的引用計數為1。調用alloc方法,你便有對新對象的所有權

· copy:制造一個對象的副本,該副本的 引用計數為1,調用者具有對副本的所有權

· retain:使對象的引用計數加1,并且獲得對象的所有權

放棄所有權的方法:

· release:使對象的引用計數減1,并且放棄對象的所有權

· autorelease:使對象的引用計數在未來的某個時候減1,并且在那個時候放棄對象的所有權

2)記憶體管理原則

  • 對你自己擁有的對象負責,你隻能釋放你擁有的對象
  • 凡是通過retain,alloc,copy等手段獲得了所有權的對象,都必須在你不在使用他的時候,由你來調用release,autorelease等手段來釋放對他的所有權
  • 在一定的代碼段内,對同一個對象所做的 copy,alloc和retain的操作次數應當與release和 autorelease操作的次數相等
  • 可以在類的dealloc方法中釋放你所占有的執行個體變量
  • 對于便利構造器和通路起來說,你沒有通過上面的這些手段獲得對象的所有權,是以在這些情況下你無須對獲得對象進行額外的釋放操作
  • autorelease隻不過意味着“預定延遲發送一條release消息”,目前的引用計數器并沒有變

集合與記憶體管理

NSMutableArray *array

.

.

.

for(int i = 0;i<10;i++)

{

NSNumber *allocedNumber = [[NSNumber alloc]initWithInteger: i];

[array addObject:allocedNumber];

[allocedNumber release];

}

屬性與記憶體管理

.h

@property(retain)NSString *name;//name聲明的屬性是retain

.m

-(void)dealloc

{

[name release];//釋放屬性

[super dealloc];

}

設定器.通路器的記憶體管理

為成員變量name寫一個設定器和通路器 同時應該在dealloc方法裡釋放對象name

-(void)dealloc

{。。。}

便利構造器記憶體管理

自動釋放池 (autoreleasepool)

  • autorelease pool不是天生的,需要手動創立。隻不過在建立一個iphone項目時,xcode會自動幫你寫好。autorelease pool的真名是NSAutoreleasePool。NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]        
  • NSAutoreleasePool内部包含一個數組(NSMutableArray),用來儲存聲明為autorelease的所有對象。如果一個對象聲明為autorelease,系統所做的工作就是把這個對象加入到這個數組中去。
  •         ClassA *obj1 = [[[ClassA alloc] init] autorelease]; //retain count = 1,把此對象加入autorelease pool中
  • NSAutoreleasePool自身在銷毀的時候,會周遊一遍這個數組,release數組中的每個成員。如果此時數組中成員的retain count為1,那麼release之後,retain count為0,對象正式被銷毀。如果此時數組中成員的retain count大于1,那麼release之後,retain count大于0,此對象依然沒有被銷毀,記憶體洩露。

使用便利構造器建立對象,因其在内部已經實作了管理記憶體,則在使用完之後不用再去釋放

+(MyObject *)myObject

{

id = [[MyObject alloc]init];

return [obj autorelease];

}

ARC