概述

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. Display与 Visibility的区别

    隐藏元素的方法有: display:none或visibility:hidden visibility:hidden可以隐藏某个元素,但隐藏的元素仍需占用与未隐藏之前一样的空间.也就是说,该元素虽然被 ...

  2. UVA - 10347 - Medians(由三中线求三角形面积)

    AC代码: #include<cstdio> #include<cmath> #include<algorithm> #include<iostream> ...

  3. &与&&,|与||的区别

    今天在做leetcode的时候,遇到了运算符的不同而导致结果不一致的问题.记录一下提醒自己 中文名称与英文名称 &:按位与(Bitwise and) &&:逻辑与(logica ...

  4. Vultr账号被锁定的几个常见原因

    很多小伙伴使用都在问Vultr账号为什么又是会出现被锁定的情况,今天我们就来了解一下Vultr账号被锁定的几个常见原因. 1.Vultr主机违规使用 按照Vultr主机商的要求,我们的Vultr主机也 ...

  5. 解决vi显示文件不能全屏的问题

    https://blog.csdn.net/ly890700/article/details/52735092 docker外:   vi ~/.vimrc

  6. Deployment的使用

    RC和RS的功能基本上是差不多的,唯一的区别就是RS支持集合的selector. RC|RS是Kubernetes的一个核心概念,当我们把应用部署到集群之后,需要保证应用能够持续稳定的运行,RC|RS ...

  7. Atcoder arc092

    E-Both Sides Merger 给你一个序列,支持两种操作,直到序列中只有一个数时停下来,使得剩下数最大,并输出选数方案. 操作1:扔掉一个最前端或最后端的元素.操作2:选取一个不在边界上的元 ...

  8. ETL工具-Kattle:查询 HTTP/WebService

      发送HTTP POST请求,获取返回内容.  发送HTTP GET请求,获取返回内容,可以从前面获取URL.参数名.参数值 通过Restful获取数据 通过webService获取数据 HTTP ...

  9. bzoj1012题解

    [解题思路] 强制在线线段树/树状数组,没什么好说的..复杂度O(mlog2m)(线段树)或O(mlog22m)(树状数组). [参考代码] (还naive的时候写的zkw真是翔..) #includ ...

  10. dfs套异或的包含性——cf986C好

    很好的题,想了半天,官方题解的解法更好 这种异或问题的包含性在北邮的校赛里就出现过,需要认真学习一下 /* y和所有合法的x合并,如果没有剪枝,那么复杂度爆炸总共要判(2^n*2^n) 可以考虑如下优 ...