AutoReleasePool

AutoReleasePool

  • 此處討論的自動(dòng)釋放池不是我們以前手動(dòng)創(chuàng)建的那種.是系統(tǒng)處理內(nèi)存相關(guān)的.

自動(dòng)釋放池和運(yùn)行循環(huán)關(guān)系

  • iOS開發(fā)中的內(nèi)存管理
    • 在iOS開發(fā)中,并沒有JAVA或C#中的垃圾回收機(jī)制
    • 在MRC中對(duì)象誰申請(qǐng),誰釋放
    • 使用ARC開發(fā),只是在編譯時(shí),編譯器會(huì)根據(jù)代碼結(jié)構(gòu)自動(dòng)添加了retain、release和autorelease.
  • 自動(dòng)釋放池
    • 標(biāo)記為autorelease的對(duì)象,會(huì)被添加到最近一次創(chuàng)建的自動(dòng)釋放池中
    • 當(dāng)自動(dòng)釋放池被銷毀或耗盡時(shí),會(huì)向自動(dòng)釋放池中的所有對(duì)象發(fā)送release消息

自動(dòng)釋放池的創(chuàng)建與銷毀

  • 此處討論的自動(dòng)釋放池不是我們以前手動(dòng)創(chuàng)建的那種.是系統(tǒng)處理內(nèi)存相關(guān)的.
  • 自動(dòng)釋放池是什么時(shí)候創(chuàng)建的?什么時(shí)候銷毀的?
    • 創(chuàng)建 : 運(yùn)行循環(huán)檢測(cè)到事件并啟動(dòng)后,就會(huì)創(chuàng)建自動(dòng)釋放池.
    • 銷毀 : 一次完整的運(yùn)行循環(huán)結(jié)束之前,會(huì)被銷毀.

運(yùn)行循環(huán)

  • 運(yùn)行循環(huán) / 消息循環(huán).
  • 作用
    • 消息循環(huán)保證應(yīng)用程序不退出.
    • 消息循環(huán)在循環(huán)的撲捉消息,然后執(zhí)行消息對(duì)應(yīng)的操作.
  • 模擬運(yùn)行循環(huán)
int main(int argc, const char * argv[]) {
    @autoreleasepool {

        while (YES) {

            // 在控制臺(tái)打印提示語
            printf("請(qǐng)輸入你要做的操作:");

            // 保存輸入的數(shù)字
            int result;

            // 接收控制太輸入的數(shù)組字
            scanf("%d",&result);

            // 判斷控制臺(tái)輸入的數(shù)字
            if (0==result) {
                NSLog(@"退出程序");
                break;
            } else if (1==result) {
                NSLog(@"點(diǎn)擊了按鈕");
            } else if (2==result) {
                NSLog(@"滾動(dòng)了視圖");
            }

            // insert code here...
//            NSLog(@"Hello, World!");
        }
    }
    return 0;
}

運(yùn)行循環(huán)和自動(dòng)釋放池的關(guān)系圖解

什么時(shí)候需要手動(dòng)創(chuàng)建自動(dòng)釋放池?

  1. 如果在循環(huán)中創(chuàng)建了大量的臨時(shí)變量的時(shí)候需要在循環(huán)一開始就手動(dòng)創(chuàng)建一個(gè)自動(dòng)釋放池

    • If you write a loop that creates many temporary objects.You may use an autorelease pool block inside the loop to dispose of those objects before the next iteration. Using an autorelease pool block in the loop helps to reduce the maximum memory footprint of the application.
  2. 如果你生成一個(gè)子線程的時(shí)候,要在線程開始執(zhí)行的時(shí)候,盡快創(chuàng)建一個(gè)自動(dòng)釋放池.否則會(huì)內(nèi)存泄露.因?yàn)樽泳€程無法訪問主線程的自動(dòng)釋放池.

    • 自定義NSOperation和NSThread時(shí)
    • If you spawn a secondary thread.You must create your own autorelease pool block as soon as the thread begins executing; otherwise, your application will leak objects. (See Autorelease Pool Blocks and Threads for details.)
      
      

關(guān)于自動(dòng)釋放池的筆試題

for (int i = 0; i < largeNumber; ++i) {
    NSString *str = @"Hello World";
    str = [str stringByAppendingFormat:@" - %d", i];
    str = [str uppercaseString];
}

// 問 : 以上代碼存在問題嗎?

延緩釋放的對(duì)象

演示延緩釋放的對(duì)象

  • 新建Person類,將Person類的編譯環(huán)境改成MRC的.
  • 手動(dòng)管理Person類的內(nèi)存.

Person類中聲明

@interface Person : NSObject

/// 名字
@property (nonatomic,copy) NSString *name;

/// 類方法實(shí)例化person對(duì)象
+ (instancetype)personWithName:(NSString *)name;

@end

Person類中實(shí)現(xiàn)

  • MRC開發(fā)中,所有返回id類型的類方法,都必須要使用autorelease標(biāo)記成延緩釋放的對(duì)象.
  • 延遲釋放的對(duì)象,在出了作用域以后,會(huì)被添加到最近一次創(chuàng)建的自動(dòng)釋放池中,等待被釋放.
+ (instancetype)personWithName:(NSString *)name
{
    // 這是個(gè)延遲釋放的對(duì)象
    Person *p = [[[Person alloc] init] autorelease];

    p.name = name;

    // 無法 return
//    [p release];

    return p;

    // 無法 release
//    [p release];
}

控制器中的使用

  • 聲明屬性
@interface ViewController ()

/// p1
@property (nonatomic,weak) Person *p1;
/// p2
@property (nonatomic,weak) Person *p2;

@end
  • Person類的實(shí)例化
- (void)viewDidLoad {
    [super viewDidLoad];

    self.p1 = [[Person alloc] init];
    self.p1.name = @"zs";
    NSLog(@"%@",self.p1.name);

    self.p2 = [Person personWithName:@"ls"];
    NSLog(@"%@",self.p2.name);

    // 手動(dòng)創(chuàng)建自動(dòng)釋放池,這個(gè)不是我們討論的
    @autoreleasepool {

    }
}
  • 測(cè)試對(duì)象的釋放
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSLog(@"%@",self.p1.name);
    NSLog(@"%@",self.p2.name);
}
  • 提問 :
    1. p2 什么時(shí)候釋放的? 自動(dòng)釋放池銷毀的時(shí)候釋放的.
    2. 自動(dòng)釋放池什么時(shí)候銷毀的?
    3. 自動(dòng)釋放池什么時(shí)候創(chuàng)建的?
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容