美文网首页
iOS原理 AutoreleasePool的嵌套分析

iOS原理 AutoreleasePool的嵌套分析

作者: 东篱采桑人 | 来源:发表于2021-02-19 19:18 被阅读0次

iOS原理 文章汇总

iOS原理 AutoreleasePool的结构分析一文中分析了单个自动释放池的结构,本文将介绍AutoreleasePool的嵌套情况。

//释放池嵌套
int main(int argc, char * argv[]) {
    
    //pool1,里面添加1个自动释放对象
    @autoreleasepool {

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

        //pool2,里面添加3个自动释放对象
        @autoreleasepool {

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

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

            //pool3,里面添加2个自动释放对象
            @autoreleasepool {

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

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

                //创建完三个pool后打印
                _objc_autoreleasePoolPrint();
            }
            
            //超出pool3的作用域时打印
            _objc_autoreleasePoolPrint();
        }
        
        //超出pool2的作用域时打印
        _objc_autoreleasePoolPrint();
    }

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

    return 0;
}

如代码所示,在main函数里嵌套创建了3个自动释放池,然后在不同时期打印内存结构。

创建后打印
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]: ##############

可以看到,线程里维护了一个自动释放池的堆栈。

  • 第一个创建的pool为最外层释放池,当前只新建了一页page
  • 嵌套创建的子pool在内存结构上来看,按顺序存于最外层释放池的page中.
超出作用域时打印
//超出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]: ##############

从三次打印结果可知,虽然子pool按顺序存在最外层释放池的page中,但每个pool还是各自管理自己的自动释放对象。

  • 当超出子pool的作用域时,子pool会被销毁,里面的对象也都会被释放。
  • 当超出最外层pool的作用域时,里面的对象会被释放,但释放池不会被销毁,会保留一个空白的page
  • 每个线程都会维护自身的自动释放池堆栈,只有当线程被销毁时,最外层pool才会被销毁。

相关文章

网友评论

      本文标题:iOS原理 AutoreleasePool的嵌套分析

      本文链接:https://www.haomeiwen.com/subject/stlbaktx.html