在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ì)被銷毀。