iOS原理 AutoreleasePool的嵌套分析

iOS原理 文章匯總

iOS原理 AutoreleasePool的結(jié)構(gòu)分析一文中分析了單個(gè)自動(dòng)釋放池的結(jié)構(gòu),本文將介紹AutoreleasePool的嵌套情況。

//釋放池嵌套
int main(int argc, char * argv[]) {
    
    //pool1,里面添加1個(gè)自動(dòng)釋放對(duì)象
    @autoreleasepool {

        NSObject *obj = [[NSObject alloc] autorelease];

        //pool2,里面添加3個(gè)自動(dòng)釋放對(duì)象
        @autoreleasepool {

            NSInteger count = 3;
            for(NSInteger i=0; i<count; i++){

                NSObject *obj = [[NSObject alloc] autorelease];
            }

            //pool3,里面添加2個(gè)自動(dòng)釋放對(duì)象
            @autoreleasepool {

                NSInteger count = 2;
                for(NSInteger i=0; i<count; i++){

                    NSObject *obj = [[NSObject alloc] autorelease];
                }

                //創(chuàng)建完三個(gè)pool后打印
                _objc_autoreleasePoolPrint();
            }
            
            //超出pool3的作用域時(shí)打印
            _objc_autoreleasePoolPrint();
        }
        
        //超出pool2的作用域時(shí)打印
        _objc_autoreleasePoolPrint();
    }

    //超出pool1作用域打印
    _objc_autoreleasePoolPrint();

    return 0;
}

如代碼所示,在main函數(shù)里嵌套創(chuàng)建了3個(gè)自動(dòng)釋放池,然后在不同時(shí)期打印內(nèi)存結(jié)構(gòu)。

創(chuàng)建后打印
objc[41194]: ##############
objc[41194]: AUTORELEASE POOLS for thread 0x114550dc0
objc[41194]: 9 releases pending.
objc[41194]: [0x7fe8e9815000]  ................  PAGE  (hot) (cold)
objc[41194]: [0x7fe8e9815038]  ################  POOL 0x7fe8e9815038
objc[41194]: [0x7fe8e9815040]    0x600001c5c060  NSObject
objc[41194]: [0x7fe8e9815048]  ################  POOL 0x7fe8e9815048
objc[41194]: [0x7fe8e9815050]    0x600001c5c070  NSObject
objc[41194]: [0x7fe8e9815058]    0x600001c5c080  NSObject
objc[41194]: [0x7fe8e9815060]    0x600001c5c090  NSObject
objc[41194]: [0x7fe8e9815068]  ################  POOL 0x7fe8e9815068
objc[41194]: [0x7fe8e9815070]    0x600001c5c0a0  NSObject
objc[41194]: [0x7fe8e9815078]    0x600001c5c0b0  NSObject
objc[41194]: ##############

可以看到,線程里維護(hù)了一個(gè)自動(dòng)釋放池的堆棧。

  • 第一個(gè)創(chuàng)建的pool為最外層釋放池,當(dāng)前只新建了一頁page
  • 嵌套創(chuàng)建的子pool在內(nèi)存結(jié)構(gòu)上來看,按順序存于最外層釋放池的page中.
超出作用域時(shí)打印
//超出pool3
objc[41194]: ##############
objc[41194]: AUTORELEASE POOLS for thread 0x114550dc0
objc[41194]: 6 releases pending.
objc[41194]: [0x7fe8e9815000]  ................  PAGE  (hot) (cold)
objc[41194]: [0x7fe8e9815038]  ################  POOL 0x7fe8e9815038
objc[41194]: [0x7fe8e9815040]    0x600001c5c060  NSObject
objc[41194]: [0x7fe8e9815048]  ################  POOL 0x7fe8e9815048
objc[41194]: [0x7fe8e9815050]    0x600001c5c070  NSObject
objc[41194]: [0x7fe8e9815058]    0x600001c5c080  NSObject
objc[41194]: [0x7fe8e9815060]    0x600001c5c090  NSObject
objc[41194]: ##############
//超出pool2
objc[41194]: ##############
objc[41194]: AUTORELEASE POOLS for thread 0x114550dc0
objc[41194]: 2 releases pending.
objc[41194]: [0x7fe8e9815000]  ................  PAGE  (hot) (cold)
objc[41194]: [0x7fe8e9815038]  ################  POOL 0x7fe8e9815038
objc[41194]: [0x7fe8e9815040]    0x600001c5c060  NSObject
objc[41194]: ##############
//超出pool1
objc[41194]: ##############
objc[41194]: AUTORELEASE POOLS for thread 0x114550dc0
objc[41194]: 0 releases pending.
objc[41194]: [0x7fe8e9815000]  ................  PAGE  (hot) (cold)
objc[41194]: ##############

從三次打印結(jié)果可知,雖然子pool按順序存在最外層釋放池的page中,但每個(gè)pool還是各自管理自己的自動(dòng)釋放對(duì)象。

  • 當(dāng)超出子pool的作用域時(shí),子pool會(huì)被銷毀,里面的對(duì)象也都會(huì)被釋放。
  • 當(dāng)超出最外層pool的作用域時(shí),里面的對(duì)象會(huì)被釋放,但釋放池不會(huì)被銷毀,會(huì)保留一個(gè)空白的page
  • 每個(gè)線程都會(huì)維護(hù)自身的自動(dòng)釋放池堆棧,只有當(dāng)線程被銷毀時(shí),最外層pool才會(huì)被銷毀。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容