1. 程式人生 > >IOS記憶體管理,ARC,MRC,自動釋放池(基礎)

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方法,輸出釋放點的提示。應該在自動釋放池結束的地方 也就是右}的地方結束。驗證如下圖:
這裡寫圖片描述