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"; ...
随机推荐
- 16. Jmeter-监听器
jmeter-监听器介绍与使用 察看结果树 Summary Report 聚合报告 Backend Listener Aggregate Graph 断言结果 Comparison Assertion ...
- CodeForces-1249C2-Good Numbers (hard version) -巧妙进制/暴力
The only difference between easy and hard versions is the maximum value of n. You are given a positi ...
- 拾遗:Git 常用操作回顾
温故而知新,可以为师矣. Git 布局 工作区---->暂存区---->本地仓库---->远程仓库 Create Repository git init PATH git add P ...
- 当引入的类库存在一个类型时,提示“xxx”和“xxx”之间的不明确引用时,消除歧义的方法
//using _2_命名空间和程序集.WidgetA; //using _2_命名空间和程序集.WidgetB; using System; using System.Collections.Gen ...
- selenium3与Python3实战 web自动化测试框架✍✍✍
selenium3与Python3实战 web自动化测试框架 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课 ...
- 7-MySQL-Ubuntu-操作数据表的基本操作(二)
修改数据表的结构 (1)向数据表中添加新的字段 alter table 表名 add 字段名 类型及约束; (2)修改字段的属性(字段的数据类型和约束) 注:modify不能修改字段名,只能修改字段 ...
- nuxt 项目启动报错(HTMLElement is not define nuxt.js)
这两天研究服务端渲染,折腾nuxt,搞得真是心累. 各种报错,nuxt 真是坑多啊,且来说说遇到哪些问题, 1. 搭建nuxt , npx create-nuxt-app <项目名> cd ...
- Reqests----Get请求之参数化
一.环境安装 >>pip install requests 注意:pip很容易就会版本升级,如果用python3的,请使用pip3 install requests 1.初始化版本 2.把 ...
- mac下Python安装路径的说明
Python安装路径的说明 mac在安装Python时, 对不同的安装方式 不同的型号均会安装在不同的文件夹下 安装方式 路径 系统默认(2.7) /System/Library/Frameworks ...
- yes - 不断输出一个字符串,直到杀死其为止
SYNOPSIS(总览) yes [OPTION]... [STRING]... DESCRIPTION(描述) 不断输出包括所有指定STRING(s)的一行,或者是`y'. --help 显示帮助并 ...