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