OC中的內存管理
1.爲什麼要管理內存
系統資源有限,會爲每個程序分配30M的內存,超過20M會收到內存警告,超過30M,sorry 系統將會終止你的應用程序。
2.怎麼樣管理內存
- 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