IOS記憶體管理,ARC,MRC,自動釋放池(基礎)
在IOS中記憶體管理幾乎是每個人必須知道的一個知識點。首先我們總結一下MRC,再通過MRC來認識ARC以及自動釋放池
1.MRC
1.1 淘汰的技術
1.2 引用計數(RC)是指alloc自動分配的一塊兒儲存空間,用於儲存持有該空間的指標個數
1.3 使用retainCount方法檢視RC的值
1.4 使用retain方法將RC加1
1.5 使用release方法將RC減1(修改RC值)
1.5.1 結果不為0,release方法直接返回
1.5.2 為0,則先呼叫dealloc,然後釋放RC所在的堆空間
1.6 retain做property的引數時,可以在set方法中自動新增持有方法,使RC加1。注意:一旦新增,必須在dealloc方法中釋放
下面我們一起看一下Demo,一起體會一下MRC的流程
showPoint方法為顯示點的座標
shoPointRC方法為顯示該空間的RC值
Point *p1 = [[Point alloc] initWithX:10 andY:20];
[self showPoint:p1];
//分配空間RC+1
[self showPointRC:p1];
Point *p2 = p1;
[p2 retain];//retain方法可以將指標p2持有其指向的空間
//p2也持有該空間,RC變成2
[self showPointRC:p1];
[p2 release];
//釋放指標P2,持有該空間的指標數變為1,RC為1
[self showPointRC:p1];
[p1 release];
// 已經釋放記憶體空間,無法顯示RC
// [self showPointRC:p1];
再看一個MRC時經常出錯的Demo.並且一起學習一下retain作為屬性的使用,以及dealloc方法
準備工作,建一個Circle類,Circle類中有一個屬性是Point類。
可以看到如果直接釋放circle類,會造成記憶體洩漏,因為center類沒有釋放。Circle類釋放了,也無法找到c.center的指標。這塊空間永遠被持有。
Point *p = [[Point alloc] initWithX:10 andY:20];
Circle *c = [[Circle alloc] init];
c.center = p;
//[c.center retain];//在property的引數中新增retain,可以自動實現此句的功能
//...
[self showPointRC:p];
[p release];
//[c.center release];//此句被放到Circle類的dealloc方法中
[c release];
}
circle類中的屬性,以及dealloc方法
.h中
@interface TRCircle : NSObject
@property(retain) TRPoint *center;
@property double radius;
@end
.m中
@implementation TRCircle
-(void)dealloc
{
[self.center release];
[super dealloc];
}
@end
2.ARC
2.1 iOS5.0開始使用,iOS7.0強制使用
2.2 不允許程式設計師呼叫retain、release、retainCount方法,而由編譯器自動新增完成其呼叫語句
3.自動釋放池
3.1 在ARC中是已經過時的技術
3.2 是一個集合,其中有許多物件
3.3 當自動釋放池的作用域結束時,池中的所有物件會被一次性全部釋放
3.4 工廠方法生成的物件一般會被放入自動釋放池
3.5 自動釋放池的巢狀
下面一起看一下自動釋放池的使用demo
@autoreleasepool
{
TRPoint *p = [[[TRPoint alloc] initWithX:10 andY:20] autorelease];
//autorelease方法將物件放入自動釋放池
//[p release];
NSLog(@"------");
}
NSLog(@"======");
我們先分析一下,我們沒有新增釋放p指標的操作,利用自動釋放池實現,那麼什麼時候實現該操作的呢。我們可以在Point類中重寫dealloc方法,輸出釋放點的提示。應該在自動釋放池結束的地方 也就是右}的地方結束。驗證如下圖: