天天看點

黑馬程式員----Objective-C學習筆記之autorelease基本使用

------Java教育訓練、Android教育訓練、iOS教育訓練、.Net教育訓練--------

1、自動釋放池及autorelease介紹

【自動釋放池】

1)在ioc程式運作過程中,會建立無數個池子,這些池子都是以棧結構(先進後出)存在的。

2)當一個對象調用autorelea時,會将這個對象放到位于棧頂得釋放池中

【自動釋放池的建立方式】

1)ios5.0以後

@autoreleasepool {
//這個大括号内部就是自動釋放池 
}
           

【autorelease】

是一種支援引用技術的記憶體管理方式

它可以【暫時儲存某個對象】,然後再記憶體池自己的排幹(drain)的時候對其中的每個對象發送release消息

【注意】這裡隻是發送release消息,如果當時的引用技術依然不為0,那麼該對象依然不會被釋放,可以用該方法來儲存某個對象,但也要注意之後要釋放該對象。

2、為什麼會有autorelease

oc的記憶體管理機制中比較重要的一條就是:誰申請,誰釋放。

考慮到這種情況,如果一個方法需要傳回一個建立的對象,該對象何時釋放?

方法内部是不會寫release來釋放對象的,因為這樣做會将對象立即釋放而傳回一個空對象,調用者也不會主動釋放該對象,因為調用者遵循【誰申請,誰釋放】的原則,那麼這個時候就會發生記憶體洩露。

【使用autorelease的好處】

1)不需要關心對象釋放的時間

2)不需要關心什麼時候調用release

3、autorelease的基本用法

【基本用法】

1)會将對象放到一個自動釋放池中

2)當自動釋放池被銷毀時,會對池子裡所有的對象發送release消息

3)會傳回對象本身

4)調用完autore方法後,下屬方法是合理的,即可以争取傳回結果,也不會造成記憶體洩露

例如:

Person *p = [Person new];
    @autoreleasepool {
        [p run];
        NSLog(@"retainCount =%lu",p.retainCount);
        //作用,把p加入到自動釋放池
        [p autorelease];
        [p run];
        NSLog(@"retainCount =%lu",p.retainCount);
 
   }
    //此時在調用會報錯(開啟僵屍對象檢測)
    //[p run];
           

列印結果;

2015-10-06 16:50:12.915 MRCDemo[2407:303] This personrun....

2015-10-06 16:50:12.917 MRCDemo[2407:303] retainCount= 1

2015-10-06 16:50:12.918 MRCDemo[2407:303] This personrun....

2015-10-06 16:50:12.918 MRCDemo[2407:303] retainCount= 1

2015-10-06 16:50:12.919 MRCDemo[2407:303] This persondead....

【分析結果】

p最後被自動釋放了

【如果autoreleasepool銷毀時對象的計數器仍不為0,就會出現記憶體洩露】

例如:

Person *p = [Person new];
    @autoreleasepool {
        [p run];
        NSLog(@"retainCount =%lu",p.retainCount);
        [p retain]; //計數器+1
        //作用,把p加入到自動釋放池
        [p autorelease];
        [p run];
        NSLog(@"retainCount =%lu",p.retainCount);
   }
           

列印結果:

2015-10-06 16:45:18.274 MRCDemo[2326:303] retainCount= 1

2015-10-06 16:45:18.276 MRCDemo[2326:303] retainCount= 2