概述

AutoreleasePool(自动释放池)是OC中的一种内存自动回收机制,它可以延迟加入AutoreleasePool中的变量release的时机。在正常情况下,创建的变量会在超出其作用域的时候release,但是如果将变量加入AutoreleasePool,那么release将延迟执行。

@autoreleasepool实现本质

在终端中使用clang -rewrite-objc命令将OC代码重写成C++的实现

__AtAutoreleasePool是C++定义类

@autoreleasepool最终实现如下

AutoreleasePoolPage

自动释放池的主要底层数据结构是:__AtAutoreleasePool 和 AutoreleasePoolPage

调用了autorelease的对象最终由AutoreleasePoolPage对象来管理

objc4源码:NSObject.mm

每一个AutoreleasePoolPage对象占用4094字节内存,本身成员占用56字节,剩下的空间用来存放autorelease对象的地址

所有的AutoreleasePoolPage对象通过双向链表的形式连接在一起

AutoreleasePoolPage管理autorelease的的对象过程

@autoreleasepool {}就对应 objc_autoreleasePoolPush(); 和  objc_autoreleasePoolPop(atautoreleasepoolobj);

objc_autoreleasePoolPush(); 内部实现:往当前hot AutoreleasePoolPage 添加 POOL_BOUNDARY,返回POOL_BOUNDARY所在的内存地址

@autoreleasepool {}代码快如果存在对象调用了autorelease,就会将对象内存地址保存至AutoreleasePoolPage

objc4 NSObject.mm 对象- (id)autorelease方法实现

添加POOL_BOUNDARY和AutoreleasePoolPage对象后如下图

每执行@autoreleasepool底层对应执行objc_autoreleasePoolPush(); 就会往AutoreleasePoolPage添加POOL_BOUNDARY,并返回POOL_BOUNDARY所在AutoreleasePoolPage的内存空间地址

@autoreleasepool{}大括号结束 内部创建的__AtAutoreleasePool对象销毁,调用析构函数objc_autoreleasePoolPop(atautoreleasepoolobj);

AutoreleasePoolPage开始从后往前遍历autorelease对象调用release方法直到objc_autoreleasePoolPop()传入的POOL_BOUNDARY地址为止

查看AutoreleasePoolPage结构

Foundation内部存在一个全局的函数 声明引用 然后在调用

控制台输出

RunLoop与autorelease

iOS程序运行 在主线程中注册了2个Observer 分别监听RunLoop的 kCFRunLoopEntry  kCFRunLoopBeforeWaiting 两个状态(通过打印主线程的RunLoop)

第一个Observer监听了kCFRunLoopEntry 会调用objc_autoreleasePoolPush

第二个Observer监听了kCFRunLoopBeforeWaiting 会调用objc_autoreleasePoolPop

MRC环境 调用的autorelease对象销毁时机

iOS程序在程序入口main函数执行@autoreleasepool也就是atautoreleasepoolobj = objc_autoreleasePoolPush();操作  保证在程序中对象可以直接调用autorelease

上图中person对象是有RunLoop来控制的,它可能是在某次RunLoop循环中,RunLoop休眠之前调用了release

ARC环境 方法中创建局部对象销毁时机

上图中person对象取决于ARC是对person添加释放代码是生成autorelease还是在方法结束之前生成release,经过调试验证ARC在方法结束前插入一句

[person release],所以ARC下局部对象是在方法结束释放。

iOS进阶四-自动释放池原理的更多相关文章

  1. 09_传智播客iOS视频教程_自动释放池与NSLog函数

    不要管什么是自动释放池,现在给你讲你也听不懂.就业班才讲,不要知道太多,知道太多对你不好.电影里面死的最惨的人就是知道最多的人.把代码写到自动释放池里面就可以了.NSLog是printf的增强版,它增 ...

  2. iOS 之 自动释放池

    向一个对象发送autorelease消息时,cocoa会将该对象的一个引用放入最新的自动释放池.作用域结束时,自动释放池会被释放,池中所有的对象也就被释放了.

  3. 63 (OC)* NSAutoreleasePool 自动释放池

    目录 0:ARC 1: 自动释放池 2:NSAutoreleasePool实现原理 3:autorelease 方法 4: Runloop和Autorelease的关系 5: Using Autore ...

  4. Objective c 自动释放池

    学IOS 的大家都知道,IOS 一共有三种内存管理方式:MRC .ARC.自动释放池.我按照我个人的理解简述一下自动释放池,希望能给大家一点帮助,如有错误请大家及时批评指正. 自动释放池有几个特点:1 ...

  5. 04-OC属性的使用、自动释放池、封装和继承

    目录: 一.IOS6声明式属性的使用 二.autoreleasepool自动释放池 三.封装.继承 回到顶部 一.IOS6声明式属性的使用 注:声明式属性默认情况下,并没有解决内存问题, 当使用@pr ...

  6. (五十八)NSObject实现多线程、自动释放池的补充

    模拟一个图片下载的场景,图片的下载需要2s,在这期间为了保证程序的流畅,应该把图片的下载放在子线程中进行. 使用NSObject的方法performSelectorInBackground方法即可实现 ...

  7. C++模拟OC的多重自动释放池

    使用过OC的都知道,OC的引用计数机制用起来还比较方便.于是就仿照OC的形式搞了个C++引用计数. 支持多重自动释放池,每次autorelease都会放到栈顶的自动释放池中. 自动释放池也可以像变量一 ...

  8. (20)Cocos2d-x中的引用计数(Reference Count)和自动释放池(AutoReleasePool)

    引用计数 引用计数是c/c++项目中一种古老的内存管理方式.当我8年前在研究一款名叫TCPMP的开源项目的时候,引用计数就已经有了. iOS SDK把这项计数封装到了NSAutoreleasePool ...

  9. autoreleasepool 自动释放池的理解

    常见的面试题:以下代码存在什么样的问题?应该如何改进? for (int i = 0; i < 100000; i++) { NSString *str = @"abc"; ...

随机推荐

  1. webogic基本使用

    文章目录 启动 注入 部署应用: 访问 启动 /root/Oracle/Middleware/user_projects/domains/weblogic/bin/startWebLogic.sh 上 ...

  2. 2、Locust压力测试 实战

    创建测试脚本 创建Test()类继承TaskSet类 创建beigong() 方法表示一个行为,访问北弓官网首页.用@task() 装饰该方法为一个任务.1表示一个Locust实例被挑选执行的权重,数 ...

  3. opencv 打开摄像头(c++)

    1,打开视频文件 2,打开IP摄像头 读取大华摄像头 大华的网络摄像头编号:DH-IPC-HFW1225M-I1-0600B,用的是RTSP协议. "rtsp://admin:dahua@1 ...

  4. 7_springboot2.x开发热部署

    概述:在开发中我们修改一个Java文件后想看到效果不得不重启应用,这导致大量时间花费,我们希望不重启应用的情况下,程序可以自动部署(热部署).有以下四种情况,如何能实现热部署. 1.模板引擎 在Spr ...

  5. bigger is greater

    题目: Lexicographical order is often known as alphabetical order when dealing with strings. A string i ...

  6. python调用tushare获取A股上市公司管理层人员信息

    接口:stk_managers 描述:获取上市公司管理层 注:tushare模块下载和安装教程,请查阅我之前的文章 积分:用户需要2000积分才可以调取,具体请参阅本文最下方积分获取办法 输入参数 名 ...

  7. 在Neo4j中删除节点中多个属性的方法

    译者言:本文介绍了如何批量删除节点的属性的方法,重点介绍了apoc.create.removeProperties 函数的使用. 今天早些时候,Irfan和我在一个数据集上做实验,运行了一些图形算法的 ...

  8. dnslog小技巧

    一.dnslog利用场景 主要针对无回显的情况. Sql-Blind RCE SSRF RFI(Remote File Inclusion) 二.原理 将dnslog平台中的特有字段payload带入 ...

  9. Linux 进程间通信 消息队列

    1.特点: 消息队列是IPC对象的一种 消息队列由消息队列ID来唯一标识 消息队列就是一个消息的列表.用户可以在消息队列中添加消息.读取消息等. 消息队列可以按照类型来发送/接收消息(消息的类型是正整 ...

  10. 泛型(Generic)接口

    泛型接口例子:一个学生有一个独一无二的ID,但是每个学生的姓名不一定是唯一的. class Program { static void Main(string[] args) { Student< ...