zoukankan      html  css  js  c++  java
  • autoreleasepool 自动释放池的理解

    常见的面试题:以下代码存在什么样的问题?应该如何改进?

        for (int i = 0; i < 100000; i++) {

                NSString *str = @"abc";

                str = [str stringByAppendingString:@"xyz"];

        }

    利用leaks查看内存泄漏情况

    可知:NSString对象str并没有马上被释放,在内存中会同时存在100000个NSString对象,造成内存急增,等100000for循环结束才释放

    改进:

        for (int i = 0; i < 100000; i++) {

            @autoreleasepool {

                NSString *str = @"abc";

                str = [str stringByAppendingString:@"xyz"];

            }

        }

    或者(注意NSAutoreleasePool ARC下不可用,必须将工程改为MRC)

        for (int i = 0; i < 100000; i++) {

            //创建一个自动释放池

            NSAutoreleasePool *pool = [NSAutoreleasePool new];

            NSString *str = @"abc";

            str = [str stringByAppendingString:@"xyz"];

            //自动释放池被销毁或耗尽,会向自动释放池中的所有对象发送release消息

            [pool drain];

        }

    利用leaks查看内存泄漏情况

    可知:不会造成内存急增,每次for循环结束NSString对象str都会释放,在内存中会只存在1个NSString对象str

    自动释放池(autoreleasepool)的工作原理:

        //@autoreleasepool {}中的代码

        void *context = objc_autoreleasePoolPush();

        //当前runloop迭代结束时进行pop操作

        objc_autoreleasePoolPop(context);

    autoreleasepool是个栈结构,对象加入池子时其实质是进行入栈Push操作,释放对象时其实质是进行出栈Pop操作。

    标记为autorelease的对象在出了作用域范围后,会被添加到最近一次创建的自动释放池中,当前runloop迭代结束时,会向自动释放池中的所有对象发送release消息,当池子里的所有对象引用计数都为0

    时该池子被销毁

  • 相关阅读:
    在loader程序中涉及到的CPU模式切换
    python 线程池的实现
    Python 面向对象程序设计
    Haskell语言学习笔记(28)Data.Map
    C++17尝鲜:在 if 和 switch 语句中进行初始化
    趣味编程:24点(Haskell版)
    Haskell语言学习笔记(27)Endo, Dual, Foldable
    Haskell语言学习笔记(26)Identity, IdentityT
    Haskell语言学习笔记(25)MonadState, State, StateT
    Haskell语言学习笔记(24)MonadWriter, Writer, WriterT
  • 原文地址:https://www.cnblogs.com/huangzs/p/9324369.html
Copyright © 2011-2022 走看看