iOS进阶四-自动释放池原理
概述
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进阶四-自动释放池原理的更多相关文章
- 09_传智播客iOS视频教程_自动释放池与NSLog函数
不要管什么是自动释放池,现在给你讲你也听不懂.就业班才讲,不要知道太多,知道太多对你不好.电影里面死的最惨的人就是知道最多的人.把代码写到自动释放池里面就可以了.NSLog是printf的增强版,它增 ...
- iOS 之 自动释放池
向一个对象发送autorelease消息时,cocoa会将该对象的一个引用放入最新的自动释放池.作用域结束时,自动释放池会被释放,池中所有的对象也就被释放了.
- 63 (OC)* NSAutoreleasePool 自动释放池
目录 0:ARC 1: 自动释放池 2:NSAutoreleasePool实现原理 3:autorelease 方法 4: Runloop和Autorelease的关系 5: Using Autore ...
- Objective c 自动释放池
学IOS 的大家都知道,IOS 一共有三种内存管理方式:MRC .ARC.自动释放池.我按照我个人的理解简述一下自动释放池,希望能给大家一点帮助,如有错误请大家及时批评指正. 自动释放池有几个特点:1 ...
- 04-OC属性的使用、自动释放池、封装和继承
目录: 一.IOS6声明式属性的使用 二.autoreleasepool自动释放池 三.封装.继承 回到顶部 一.IOS6声明式属性的使用 注:声明式属性默认情况下,并没有解决内存问题, 当使用@pr ...
- (五十八)NSObject实现多线程、自动释放池的补充
模拟一个图片下载的场景,图片的下载需要2s,在这期间为了保证程序的流畅,应该把图片的下载放在子线程中进行. 使用NSObject的方法performSelectorInBackground方法即可实现 ...
- C++模拟OC的多重自动释放池
使用过OC的都知道,OC的引用计数机制用起来还比较方便.于是就仿照OC的形式搞了个C++引用计数. 支持多重自动释放池,每次autorelease都会放到栈顶的自动释放池中. 自动释放池也可以像变量一 ...
- (20)Cocos2d-x中的引用计数(Reference Count)和自动释放池(AutoReleasePool)
引用计数 引用计数是c/c++项目中一种古老的内存管理方式.当我8年前在研究一款名叫TCPMP的开源项目的时候,引用计数就已经有了. iOS SDK把这项计数封装到了NSAutoreleasePool ...
- autoreleasepool 自动释放池的理解
常见的面试题:以下代码存在什么样的问题?应该如何改进? for (int i = 0; i < 100000; i++) { NSString *str = @"abc"; ...
随机推荐
- redis-trib.rb创建集群失败
yum安装ruby: yum install -y rubyyum install -y rubygems //安装rubygemgem install redis //安装redis的接口包gem ...
- 021_IO流
IO流 I——input 输入 O——Output 输出 文件 File 所有文件类的父类 创建方式 File file = new File("文件路径"); 文件对象常用的方法 ...
- Java性能调优攻略全分享,5步搞定!(附超全技能图谱)
对于很多研发人员来说,Java 性能调优都是很头疼的问题,为什么这么说?如今,一个简单的系统就囊括了应用程序.数据库.容器.操作系统.网络等技术,线上一旦出现性能问题,就可能要你协调多方面组件去进行优 ...
- java-Day01
什么是java语言 1995由美国SUN公司推出的高级编程语言(后2009年甲骨文公司收购SUN公司) 常用的DOS命令 盘符切换命令:盘符: 查看当前文件夹:dir 进入文件命令:cd 文件夹名 退 ...
- Oracle中NEXTVAL 和 CURRVAL的使用
能够通过在 SQL 语句中使用 NEXTVAL 或 CURRVAL 运算符来訪问序列的值.必须用以 sequence.NEXTVAL 或sequence.CURRVAL 格式驻留在同一个数据库中的序列 ...
- 2018-2-13-win10-uwp-iot
title author date CreateTime categories win10 uwp iot lindexi 2018-2-13 17:23:3 +0800 2018-2-13 17:2 ...
- tomcat之redis
Nginx服务器:[root@nginx ~]# vim /usr/local/nginx/conf/nginx.confupstream tomcat_pool { server 192.168.2 ...
- 【学术篇】SPOJ FTOUR2 点分治
淀粉质入门第一道 (现在个人认为spoj比bzoj要好_(:з」∠)_ 关于点分治的话推荐去看一看漆子超的论文>>>这里这里<<< 之前一直试图入点分治坑, 但是因 ...
- pandas-pd.read_csv
read_csv()接受以下常见参数: 参数 中文名 参数类型 默认参数 参数功能 说明 filepath_or_buffer various :文件路径.URL.或者 是read()函数返回的对 ...
- python_django_views视图模块
视图(views.py):接收web请求,并响应web请求 在视图响应web请求的过程中,响应文件可能是网页,也可能是json数据 若响应的是网页,我们可分为: 地址重定向的网页请求(子类HttpRe ...