前言:当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,因此自动释放池 定义的作用域内的其它对象可以向它发送消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。

1. ojc-c 是通过一种"referring counting"(引用计数)的方式来管理内存的, 对象在开始分配内存(alloc)的时候引用计数为一,以后每当碰到有alloc,new,copy,retain的时候引用计数都会加一, 每当碰到release和autorelease的时候引用计数就会减一,如果此对象的计数变为了0, 就会被系统销毁.
2. NSAutoreleasePool 就是用来做引用计数的管理工作的,这个部分后面会详细说到.
3. autorelease和release没什么区别,只是引用计数减一的时机不同而已,autorelease会在对象的使用真正结束的时候才做引用计数减一.
4.设定项目编译环境为ARC下时,编译器会帮助我们在程序的入口main函数就调用NSAutoreleasePool,这样保证程序中不调用NSAutoreleasePool,但在退出时自动释放

1.NSAutoreleasePool是什么?
 NSAutoreleasePool实际上是个对象引用计数自动处理器,在官方文档中被称为是一个类。

NSAutoreleasePool可以同时有多个,它的组织是个栈,总是存在一 个栈顶pool,也就是当前pool,每创建一个pool,就往栈里压一个,改变当前pool为新建的pool,然后,每次给pool发送drain消 息,就弹出栈顶的pool,改当前pool为栈里的下一个 pool。

2.NSAutoreleasePool可以用来做什么,怎么用?

NSAutoreleasePool可以在一定程度上帮助我们苹果开发程序员管理内存,让我们的工作更加严密,简便。

  1)在ARC项目中,系统会自动帮助我们在程序中嵌入NSAutoreleasePool,此为苹果公司程序员在写这个编译器的时候设定的;

  2)在MRC项目中,我们需要自己去创建NSAutoreleasePool类对象去帮助我们管理内存;

  3)使用应注意:

      a.在ARC项目中我们同样可以创建NSAutoreleasePool类对象去帮助我们更精确的管理内存问题。

      b. NSAutoreleasePool的管理范围是在NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];与[pool release];之间的对象

      c..既然ARC项目中设置了ARC,为什么还要使用@autoreleasepool?(注意a的案例解释)

          ARC 并不是舍弃了 @autoreleasepool,而是在编译阶段帮你插入必要的 retain/release/autorelease 的代码调用。

          所以,跟你想象的不一样,ARC 之下依然是延时释放的,依然是依赖于 NSAutoreleasePool,跟非 ARC 模式下手动调用那些函数本质上毫无差别,只是编译          器来做会保证引用计数的正确性。

          参考:      Retain count semantics in ARC

                   What's @autoreleasepool

  • d.NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
    当执行[pool autorelease]的时候,系统会进行一次内存释放,把autorelease的对象释放掉,如果没有NSAutoreleasePool , 那这些内存不会释放
    注意,对象并不是自动被加入到当前pool中,而是需要对对象发送autorelease消息,这样,对象就被加到当前pool的管理里了。当当前pool接受到drain消息时,它就简单的对它所管理的所有对象发送release消息。(如例子1)
  • e.在ARC项目中.不能直接使用autorelease pools,而是使用@autoreleasepool{},
    @autoreleasepool{}比直接使用NSAutoreleasePool效率高。不使用ARC的时候也可以使用(autorelease嵌套)

  4)使用例子:

例子1:

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString* nsstring;
char* cstring = "Hello CString";
nsstring = [NSString stringWithUTF8String:cstring];
[pool release];(这一行代码就是在给pool发送drain消息了)

官方API摘抄翻译:

3.autorelease的原理是什么?

Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当 前的Autorelease pool中,当该pool被释放时,该pool中的所有Object会被调用Release。

4.!!!autorelease何时释放?

对于autorelease pool本身,会在如下两个条件发生时候被释放(详细信息请参见第5条)

1)、手动释放Autorelease pool

2)、Runloop结束后自动释放

对于autorelease pool内部的对象在引用计数的retain == 0的时候释放。release和autorelease pool 的 drain都会触发retain--事件。

5、autorelease释放的具体原理是什么?

要搞懂具体原理,则要先要搞清楚autorelease何时会创建。

我们的程序在main()调用的时候会自动调用一个autorelease,然后在每一个 Runloop, 系统会隐式创建一个Autorelease pool,这样所有的release pool会构成一个象CallStack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的 Autorelease pool(main()里的autorelease)会被销毁,这样这个pool里的每个Object会被release。

可以把autorelease pool理解成一个类似父类与子类的关系,main()创建了父类,每个Runloop自动生成的或者开发者自定义的autorelease pool都会成为该父类的子类。当父类被释放的时候,没有被释放的子类也会被释放,这样所有子类中的对象也会收到release消息。

那什么是一个Runloop呢? 一个UI事件,Timer call, delegate call, 一个鼠标事件,键盘按下(MAC OSX),或者iphone上的触摸事件,异步http连接下后当接收完数据时,都会是一个新的Runloop。

一般来说,消息循环运行一次是毫秒级甚至微秒级的,因此autorelease的效率仍然是非常高的,确实是一个巧妙的设计。

6、使用有什么要注意的?

1)、NSAutoreleasePool可以创建一个autorelease pool,但该对象本身也需要被释放,如:

  1. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init;
  2. // Code benefitting from a local autorelease pool.
  3. [pool release];

复制代码

在引用计数环境下,使用[pool release]或[pool drain]效果是相同的,drain仅适用于max os高版本,低版本不适用,而release通用,其它并无太大差别。

2)、在ARC下,不能使用上述方式调用autorelease,而应当使用@autoreleasepool,如:

  1. @autoreleasepool {
  2. // Code benefitting from a local autorelease pool.
  3. }

复制代码

3)、尽量避免对大内存使用该方法,如图片。对于这种延迟释放机制,还是尽量少用,最好只用在方法内返回小块内存申请地址值的情况下,且参考和领会OC的一些系统方法,如:[NSString stringWithFormat:]。

4)、不要把大量循环操作放到同一个NSAutoreleasePool之间,这样会造成内存峰值的上升。

7、关于多线程,有什么要注意的?

我还未实际使用到,在官方API翻译出类似如下语句:

1)、对于不同线程,应当创建自己的autorelease pool。如果应用长期存在,应该定期drain和创建新的autorelease pool

下面这句话摘自官方API,大概是说多线程中如果没有使用到cocoa的相关调用,则不需要创建autorelease pool,我一直没有理解透彻

If, however, your detached thread does not make Cocoa calls, you do not need to create an autorelease pool.

2)、如果不是使用的NSThread,就不要用aoturelease pool,除非你是多线程模式(multithreading mode) ,可以使用NSThread的isMultiThreaded方法测试你的应用是否是多线程模式

PS:

我把它理解为:新开线程最好实现NSAutoreleasePool(当 我们点击一个App中的一个按钮或者其他可以触碰开启新业务的UI控件,在程序里面就会自动开启一条新线程,当我们不用这个业务的时候,就需要程序帮我们 提前在“程序的主窗口的所有代码编译结束后”之前关闭这条线程以优化线程的使用,一定程度上尽量避免线程开启太多占用CPU严重引起的卡顿问题)(业务逻 辑处理-业务线程优化)
详细可以参考官方API的NSAutoreleasePool Class Reference

转载于:https://www.cnblogs.com/LifeTechnologySupporter/p/5232357.html

iOS---NSAutoreleasePool自动释放原理及详解相关推荐

  1. (转)Objective-C Autorelease Pools(自动释放池)详解

    本篇将给您介绍"Autorelease Pools"(自动释放池)在应用中的使用技巧. 1,Autorelease Pools概要 一个"Autorelease Pool ...

  2. iOS中的HotFix方案总结详解

    iOS中的HotFix方案总结详解 相信HotFix大家应该都很熟悉了,今天主要对于最近调研的一些方案做一些总结.iOS中的HotFix方案大致可以分为四种: WaxPatch(Alibaba) Dy ...

  3. 李洪强iOS经典面试题156 - Runtime详解(面试必备)

    李洪强iOS经典面试题156 - Runtime详解(面试必备)   一.runtime简介 RunTime简称运行时.OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制. 对于C ...

  4. [Python图像处理] 三十三.图像各种特效处理及原理万字详解(毛玻璃、浮雕、素描、怀旧、流年、滤镜等)...

    此文转载自:https://blog.csdn.net/Eastmount/article/details/111568397#commentBox 该系列文章是讲解Python OpenCV图像处理 ...

  5. iOS 开发:『Runtime』详解(二)Method Swizzling

    本文用来介绍 iOS 开发中『Runtime』中的黑魔法Method Swizzling. 通过本文,您将了解到: Method Swizzling(动态方法交换)简介 Method Swizzlin ...

  6. 抖音推荐算法原理全文详解

    阅读目录 一.系统概览 二.内容分析 三.用户标签 四.评估分析 五.内容安全 抖音推荐算法原理全文详解 本次分享将主要介绍今日头条推荐系统概览以及内容分析.用户标签.评估分析,内容安全等原理. 回到 ...

  7. php自动加载类与路由,PHP实现路由与类自动加载步骤详解

    这次给大家带来PHP实现路由与类自动加载步骤详解,PHP实现路由与类自动加载步骤详解的注意事项有哪些,下面就是实战案例,一起来看一下. 项目目录如下 入口文件index.php<?php def ...

  8. endnotex7怎么导入中文文献_EndNote X7自动导入PDF功能详解 | 科研动力

    在Endnote X7 新功能简介一文中对于EndNote X7的自动导入PDF功能作了一简要介绍,但是有些人对于EndNote自动导入PDF的功能还是有疑问,本文就EndNote如何自动导入PDF功 ...

  9. python离线包安装_python 通过pip freeze、dowload打离线包及自动安装的过程详解(适用于保密的离线环境...

    python的pip是其包管理工具,相当方便好用.本文只介绍pip 如何通过其freeze命令打离线包,及其离线包的安装脚本.这个知识点,特别适用于不适合连通互联网,设备需要物理隔绝,保密要求严格的客 ...

  10. [crypto]-02-非对称加解密RSA原理概念详解

    说明:本文使用的数据来自网络,重复的太多了,也不知道哪篇是原创. 算法原理介绍 step 说明 描述 备注 1 找出质数 P .Q - 2 计算公共模数 N = P * Q - 3 欧拉函数 φ(N) ...

最新文章

  1. python tensor_Python深度学习 2.3 张量运算
  2. 西门子smart200以太网通讯协议
  3. SPI通信协议:单片机spi通信接口什么意思,spi接口干什么用的?
  4. post xmlrpc.php,宝塔面板WordPress /xmlrpc.php经常被post恶意数据
  5. 第三次作业-结对编程
  6. 用DirectionalViewPager代替ViewPager
  7. 微型计算机一般只具有定点运算功能对吗,大学计算机基础模拟卷2及答案剖析.doc...
  8. win10 office 家庭和学生版 excel个人工作簿 PERSONAL.XLSB 的保存位置
  9. 详解机器学习之感知机理论与实践
  10. How to recover deleted data from SQL Server
  11. 有的字体,用黑色渲染,效果是灰色
  12. 三菱PLC编程指令简介
  13. 全球人工智能与机器学习大会PPT
  14. 什么是存储过程?有什么优点?
  15. mysql 无法启动 0xc000007b,windows安装mysql5.7教程 (MSVCR120.dll丢失。应用程序无法正常启动0xc000007b)...
  16. java 中== 和equal的区别
  17. 你不知道的云南隐藏景点_我是亲民_新浪博客
  18. 2021潞河中学内高班高考成绩查询,潞河中学2018小升初入学攻略(含入学途径、中高考成绩)...
  19. 如何关闭 Linux 中的嘟嘟声
  20. python+微信+腾讯智能闲聊

热门文章

  1. LINUX安装依赖库的解决办法
  2. 成功的人不是最聪明的那个人,但绝对是一个交流很棒的人
  3. 重装驱动:Failed to initialize NVML: Driver/library version mismatch
  4. 警告解决办法:class xxxx has virtual method but non-virtual destructor
  5. ajax异步加载页面元素,使用jQuery的AJAX封装函数load()异步加载多个页面的相同页头/页尾(注意:js无法操作动态生成的网页元素)...
  6. html5 小车动画_HTML5 实现小车动画效果(Canvas/CSS3/JQuery)
  7. Linux开机加载新内核,linux-kernel – 为什么加载内核地址,ramdisk在启动时很重要?...
  8. c++ 类与默认函数、包括构造函数和析构函数的特点
  9. 公众号openid能做用户识别_四川养老公众号开发哪里能做
  10. 公式中的引号怎么输_Excel计数函数中这些奇怪的参数让我百思不得其解!